Преглед на файлове

可以显示视频图像了

张洋 преди 1 ден
родител
ревизия
d323610ff4

+ 5 - 3
bin/Win32/Debug/zhipuzi_pos_windows/skin/aixuexi_page.xml

@@ -13,18 +13,20 @@
             <VerticalLayout name="aixuexi_page_paishe_layout" width="500" padding="0,0,0,0" bordercorner="10,10" bkcolor="#FFFFFFFF" autocalcwidth="true">
                 <Label name="aixuexi_page_xuanzhong_food_name" text="未选中商品" heiht="40" padding="10,10,10,10" font="aixuexi_1"></Label>
 
-                <Label name="aixuexi_page_xuanzhong_food_name" wordbreak="true" text="智铺子AI识别默认就能识别几百种常见的水果蔬菜,这些常见的水果蔬菜无需学习,只有智铺子AI无法正常识别的冷门商品或非水果蔬菜类商品才需要学习。" heiht="60" padding="10,0,10,10" font="3"></Label>
+                <Label name="aixuexi_page_xuanzhong_food_name" wordbreak="true" height="80" text="智铺子AI识别默认就能识别几百种常见的水果蔬菜,这些常见的水果蔬菜无需学习,只有智铺子AI无法正常识别的冷门商品或非水果蔬菜类商品才需要学习。" heiht="60" padding="10,0,10,10" font="3"></Label>
 
                 <Control autocalcwidth="true" height="1" bkcolor="#FFEBE8E8" padding="10,0,10,0"></Control>
 
-                <Control name="image" height="350" bkimage="file='food_image_default.png'" padding="10,0,10,0"></Control>
+                <Control name="image" width="480" height="360" bkimage="file='food_image_default.png'" padding="10,0,10,0"></Control>
 
-                <HorizontalLayout height="50" padding="0,10,0,0">
+                <HorizontalLayout height="50" padding="0,20,0,0">
                     <Control></Control>
                         <Button name="aixuexi_page_paishe_btn" width="150" height="50" text="拍摄并学习" textcolor="#FFFFFFFF" normalimage="file='btn_green_zhengchang.png' corner='5,5,5,5'" hotimage="file='btn_green_xuanfu.png' corner='5,5,5,5'" pushedimage="file='btn_green_dianji.png' corner='5,5,5,5'" />
                     <Control></Control>
                 </HorizontalLayout>
 
+                <Control></Control>
+
                 
             </VerticalLayout>
 

+ 2 - 1
zhipuzi_pos_windows/helper/define.h

@@ -66,4 +66,5 @@
 #define WM_MYHOTKEY_SHOUKUAN 10817
 
 //AI识别相关的
-#define WM_AI_RECOGNITION_SUCCESS 10901
+#define WM_AI_RECOGNITION_SUCCESS 10901
+#define WM_AI_XUEXI_UPDATE 10902

+ 108 - 3
zhipuzi_pos_windows/page/CAIxuexiPageUI.cpp

@@ -1,21 +1,39 @@
 #include "CAIxuexiPageUI.h"
 
+#include "../wnd/CMainWnd.h"
+#include "../worker/CVideoCaptureWorker.h"
+
 #define WM_TIMER_VIDEO_UPDATE 200002
 
 CAIxuexiPageUI::CAIxuexiPageUI()
 {
-
+	m_hBitmap = NULL;
+	m_hMemDC = NULL;
 }
 
 CAIxuexiPageUI::~CAIxuexiPageUI()
 {
-	::KillTimer(NULL, WM_TIMER_VIDEO_UPDATE);
+	if (m_hBitmap)
+	{
+		DeleteObject(m_hBitmap);
+		m_hBitmap = NULL;
+	}
+	if (m_hMemDC)
+	{
+		DeleteDC(m_hMemDC);
+		m_hMemDC = NULL;
+	}
 }
 
 
 void CAIxuexiPageUI::InitShow()
 {
-	::SetTimer(NULL, WM_TIMER_VIDEO_UPDATE, 1500, NULL);
+	if (m_isFirstInit)
+	{
+		m_isFirstInit = false;
+		
+		std::thread(&CAIxuexiPageUI::HandleUpdateVideo, this).detach();
+	}	
 }
 
 //处理按钮点击类事件
@@ -50,5 +68,92 @@ void CAIxuexiPageUI::HandleTextCapture(std::string content)
 
 bool CAIxuexiPageUI::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
+	if (uMsg == WM_AI_XUEXI_UPDATE)
+	{
+		UpdateVideoShow();
+	}
+
 	return false;
 }
+
+void CAIxuexiPageUI::HandleUpdateVideo()
+{
+	while (true)
+	{
+		if (m_pMainWnd->GetCurPageName() != CMainWnd::AIXUEXI)
+		{
+			Sleep(30);
+			continue;
+		}
+
+		cv::Mat img;
+		CVideoCaptureWorker::GetInstance()->GetFrame(img);
+
+		if (img.empty())
+		{
+			Sleep(30);
+			continue;
+		}
+
+		if (img.type() != CV_8UC3)
+		{
+			// 仅支持 3 通道彩色图像
+			cvtColor(img, img, cv::COLOR_GRAY2BGR);
+		}
+
+		//缩放尺寸,适合在界面上展示,过大过小都不好看,这个尺寸是根据界面上image控件的大小来定的,可以根据实际情况调整
+		cv::resize(img, img, cv::Size(480, 360), 0, 0, cv::INTER_LINEAR);
+
+		// 创建或更新位图
+		HDC hDC = GetDC(NULL);
+		if (m_hBitmap)
+		{
+			DeleteObject(m_hBitmap);
+		}
+
+		BITMAPINFO bmi = { 0 };
+		bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+		bmi.bmiHeader.biWidth = img.cols;
+		bmi.bmiHeader.biHeight = -img.rows; // 翻转 Y 轴(OpenCV 与 GDI 坐标方向相反)
+		bmi.bmiHeader.biPlanes = 1;
+		bmi.bmiHeader.biBitCount = 24;
+		bmi.bmiHeader.biCompression = BI_RGB;
+
+		m_hBitmap = CreateDIBitmap(hDC, &bmi.bmiHeader, CBM_INIT, img.data, &bmi, DIB_RGB_COLORS);
+		ReleaseDC(NULL, hDC);
+
+		::PostMessage(m_pMainWnd->GetHWND(), WM_AI_XUEXI_UPDATE, 0, 0);
+
+		// 控制帧率,避免过度占用 CPU,30 FPS 大约是每 33 毫秒更新一次
+		Sleep(1000 / 30);
+	}
+}
+
+void CAIxuexiPageUI::UpdateVideoShow()
+{
+	HDC hDC = m_pManager->GetPaintDC();
+
+	if (!m_hMemDC)
+	{
+		m_hMemDC = CreateCompatibleDC(hDC);
+	}
+
+	HBITMAP hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
+	BITMAP bm;
+	GetObject(m_hBitmap, sizeof(BITMAP), &bm);
+
+	CControlUI* pImage = static_cast<CControlUI*>(this->FindSubControl(_T("image")));
+	if (!pImage)
+	{
+		return;
+	}
+
+	RECT imageRect = pImage->GetPos();
+
+	StretchBlt(hDC, imageRect.left, imageRect.top, imageRect.right - imageRect.left,
+		imageRect.bottom - imageRect.top, m_hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
+
+	SelectObject(m_hMemDC, hOldBitmap);
+
+	return;
+}

+ 13 - 0
zhipuzi_pos_windows/page/CAIxuexiPageUI.h

@@ -32,5 +32,18 @@ public:
 
 	//处理自定义消息,各个页面处理各个页面自己的(是自己处理的消息返回true,不是自己处理的消息返回false)
 	bool HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+	void HandleUpdateVideo();
+
+	void UpdateVideoShow();
+
+
+private:
+	std::wstring m_newImage;
+
+	bool m_isFirstInit = true;
+
+	HBITMAP m_hBitmap;
+	HDC m_hMemDC;
 };
 

+ 5 - 0
zhipuzi_pos_windows/wnd/CMainWnd.h

@@ -135,6 +135,11 @@ public:
 		return m_pages[pageName];
 	}
 
+	MainPageName GetCurPageName()
+	{
+		return m_curPageName;
+	}
+
 	bool GetIsKuaijiejianSetting()
 	{
 		return m_IsKuaijiejian;

+ 1 - 1
zhipuzi_pos_windows/worker/CDiandanAIShibieWorker.cpp

@@ -69,7 +69,7 @@ void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 			}
 
 			float weight = atof(CChengzhongWorker::GetInstance()->GetWeight().c_str());
-			if (weight < -0.01)
+			if (weight < 0.01)
 			{
 				//说明没有重量,没放东西到秤上面,那么就不识别
 				Sleep(100);

+ 5 - 2
zhipuzi_pos_windows/worker/CVideoCaptureWorker.cpp

@@ -99,10 +99,13 @@ void CVideoCaptureWorker::HandleVideoCapture()
             continue;
         }
 
+		// 控制帧率,避免占用过多CPU资源,这里设置为30帧每秒
+		Sleep(1000 / 30);
+
 		//什么都不用做,只需要把摄像头读取的帧放在成员变量里就行,后续其他地方需要用到摄像头数据的时候直接从成员变量里取就行了
         // 显示摄像头帧(可选)
-        // cv::imshow("Camera", m_frame);
-		// if (cv::waitKey(30) >= 0) break; // 按任意键退出
+        //cv::imshow("Camera", m_frame);
+		//if (cv::waitKey(30) >= 0) break; // 按任意键退出
     }
 
     // 程序走到这里,说明收银系统被退出了,这里不释放资源也无所谓了,释放资源太慢了要卡住几百毫秒