张洋 1 day ago
parent
commit
ff73d5bc42

+ 27 - 34
DuiLib/Layout/UITileLayout.cpp

@@ -83,18 +83,14 @@ namespace DuiLib
 		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
 		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
 			rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
 			rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
 
 
-		// ========== 核心:固定子控件尺寸(不再动态计算) ==========
 		SIZE szItem = GetItemSize();
 		SIZE szItem = GetItemSize();
-		// 确保ItemSize有效,避免除0
-		if (szItem.cx <= 0) szItem.cx = 100; // 兜底默认宽度
-		if (szItem.cy <= 0) szItem.cy = 100; // 兜底默认高度
+		if (szItem.cx <= 0) szItem.cx = 100;
+		if (szItem.cy <= 0) szItem.cy = 100;
 
 
-		// ========== 核心:固定列数计算(基于固定宽度+水平间距) ==========
-		int cxItemWithPadding = szItem.cx + m_iChildPadding; // 单个子控件占宽(含水平间距)
+		int cxItemWithPadding = szItem.cx + m_iChildPadding;
 		m_nColumns = (rc.right - rc.left) / cxItemWithPadding;
 		m_nColumns = (rc.right - rc.left) / cxItemWithPadding;
 		if (m_nColumns <= 0) m_nColumns = 1;
 		if (m_nColumns <= 0) m_nColumns = 1;
 
 
-		// 滚动条兼容处理
 		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
 		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
 		{
 		{
 			int nTotalWidth = rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange();
 			int nTotalWidth = rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange();
@@ -102,15 +98,14 @@ namespace DuiLib
 			if (m_nColumns <= 0) m_nColumns = 1;
 			if (m_nColumns <= 0) m_nColumns = 1;
 		}
 		}
 
 
-		// 布局初始化
 		int cyNeeded = 0;
 		int cyNeeded = 0;
 		int iCount = 0;
 		int iCount = 0;
+		int nVisibleCount = 0;
 		POINT ptTile = { rc.left, rc.top };
 		POINT ptTile = { rc.left, rc.top };
 
 
-		// 垂直滚动条偏移
 		if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
 		if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
 			ptTile.y -= m_pVerticalScrollBar->GetScrollPos();
 			ptTile.y -= m_pVerticalScrollBar->GetScrollPos();
-		// 水平滚动条偏移
+
 		int iPosX = rc.left;
 		int iPosX = rc.left;
 		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
 		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
 		{
 		{
@@ -118,7 +113,6 @@ namespace DuiLib
 			ptTile.x = iPosX;
 			ptTile.x = iPosX;
 		}
 		}
 
 
-		// ========== 遍历子控件:固定宽高+固定间距布局 ==========
 		for (int it1 = 0; it1 < m_items.GetSize(); it1++)
 		for (int it1 = 0; it1 < m_items.GetSize(); it1++)
 		{
 		{
 			CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
 			CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
@@ -129,22 +123,15 @@ namespace DuiLib
 				continue;
 				continue;
 			}
 			}
 
 
-			// ========== 核心1:固定子控件位置(无动态尺寸计算) ==========
+			nVisibleCount++;
+
 			RECT rcTile = {
 			RECT rcTile = {
-				ptTile.x,                  // 左
-				ptTile.y,                  // 上
-				ptTile.x + szItem.cx,      // 右(固定宽度)
-				ptTile.y + szItem.cy       // 下(固定高度)
+				ptTile.x,
+				ptTile.y,
+				ptTile.x + szItem.cx,
+				ptTile.y + szItem.cy
 			};
 			};
 
 
-			// 忽略子控件自身padding,强制使用固定尺寸(如需保留padding可删除此段)
-			// RECT rcPadding = pControl->GetPadding();
-			// rcTile.left += rcPadding.left;
-			// rcTile.right -= rcPadding.right;
-			// rcTile.top += rcPadding.top;
-			// rcTile.bottom -= rcPadding.bottom;
-
-			// ========== 核心2:强制子控件尺寸为ItemSize(覆盖所有动态计算) ==========
 			RECT rcPos = {
 			RECT rcPos = {
 				rcTile.left,
 				rcTile.left,
 				rcTile.top,
 				rcTile.top,
@@ -153,27 +140,33 @@ namespace DuiLib
 			};
 			};
 			pControl->SetPos(rcPos, bNeedInvalidate);
 			pControl->SetPos(rcPos, bNeedInvalidate);
 
 
-			// ========== 核心3:固定间距更新坐标 ==========
 			iCount++;
 			iCount++;
-			// 换行:重置X坐标,Y坐标 += 固定高度 + 垂直间距
 			if (iCount % m_nColumns == 0)
 			if (iCount % m_nColumns == 0)
 			{
 			{
 				ptTile.x = iPosX;
 				ptTile.x = iPosX;
-				ptTile.y += szItem.cy + m_iChildPadding; // 垂直间距 = m_iChildPadding
+				ptTile.y += szItem.cy + m_iChildPadding;
 			}
 			}
-			// 不换行:X坐标 += 固定宽度 + 水平间距
 			else
 			else
 			{
 			{
-				ptTile.x += szItem.cx + m_iChildPadding; // 水平间距 = m_iChildPadding
+				ptTile.x += szItem.cx + m_iChildPadding;
 			}
 			}
+		}
 
 
-			// 更新总高度(用于滚动条)
-			cyNeeded = ptTile.y - rc.top + szItem.cy;
-			if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
-				cyNeeded += m_pVerticalScrollBar->GetScrollPos();
+		// 修正1:按“实际行数”计算内容高度,避免最后一个元素正好换行时多算一行
+		if (nVisibleCount > 0)
+		{
+			int nRows = (nVisibleCount - 1) / m_nColumns + 1;
+			cyNeeded = nRows * szItem.cy + (nRows - 1) * m_iChildPadding;
 		}
 		}
+		else
+		{
+			cyNeeded = 0;
+		}
+
+		// 修正2:滚动中的内容总高度需要补回当前滚动偏移
+		if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
+			cyNeeded += m_pVerticalScrollBar->GetScrollPos();
 
 
-		// 处理滚动条
 		ProcessScrollBar(rc, 0, cyNeeded);
 		ProcessScrollBar(rc, 0, cyNeeded);
 	}
 	}
 }
 }

BIN
bin/Win32/Debug/zhipuzi_pos_windows/DuiLib_d.dll


+ 1 - 1
bin/Win32/Debug/zhipuzi_pos_windows/skin/aixuexi_page_fooditem.xml

@@ -3,7 +3,7 @@
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="1" name="微软雅黑" size="14" />
 	<Font id="1" name="微软雅黑" size="14" />
 	
 	
-	<AIXuexiFoodItem name="aixuexi_page_fooditem" bkcolor="#FFFFFFFF" padding="0,0,5,5">
+	<AIXuexiFoodItem name="aixuexi_page_fooditem" bkcolor="#FFFFFFFF" padding="0,0,0,0" width="130" height="220">
 		<Control name="image" height="130" bkimage="file='food_image_default.png'" padding="0,0,0,0"></Control>
 		<Control name="image" height="130" bkimage="file='food_image_default.png'" padding="0,0,0,0"></Control>
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>

+ 1 - 1
bin/Win32/Debug/zhipuzi_pos_windows/skin/aixuexi_page_fooditem_wutu.xml

@@ -3,7 +3,7 @@
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="1" name="微软雅黑" size="14" />
 	<Font id="1" name="微软雅黑" size="14" />
 	
 	
-	<ShangpinFoodItem name="shangpin_fooditem" bkcolor="#FFFFFFFF" padding="0,0,5,5">
+	<ShangpinFoodItem name="shangpin_fooditem" bkcolor="#FFFFFFFF" padding="0,0,0,0" width="130" height="90">
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
 	</ShangpinFoodItem>
 	</ShangpinFoodItem>

+ 2 - 2
bin/Win32/Debug/zhipuzi_pos_windows/skin/shangpin_fooditem.xml

@@ -3,11 +3,11 @@
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="1" name="微软雅黑" size="14" />
 	<Font id="1" name="微软雅黑" size="14" />
 	
 	
-	<ShangpinFoodItem name="shangpin_fooditem" bkcolor="#FFFFFFFF" padding="0,0,5,5">
+	<ShangpinFoodItem name="shangpin_fooditem" bkcolor="#FFFFFFFF" padding="0,0,0,0" width="130" height="220">
 		<Control name="image" height="130" bkimage="file='food_image_default.png'" padding="0,0,0,0"></Control>
 		<Control name="image" height="130" bkimage="file='food_image_default.png'" padding="0,0,0,0"></Control>
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
-	
+			
 		<Label name="kucun" visible="false" width="50" height="35" font="1" text="已售空" float="true" pos="0,185,130,220" textcolor="#FFFFFFFF" bkcolor="#FF696969" align="center"></Label>
 		<Label name="kucun" visible="false" width="50" height="35" font="1" text="已售空" float="true" pos="0,185,130,220" textcolor="#FFFFFFFF" bkcolor="#FF696969" align="center"></Label>
 	</ShangpinFoodItem>
 	</ShangpinFoodItem>
 </Window>
 </Window>

+ 1 - 1
bin/Win32/Debug/zhipuzi_pos_windows/skin/shangpin_fooditem_wutu.xml

@@ -3,7 +3,7 @@
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="shangpin_price" name="微软雅黑" size="18" />
 	<Font id="1" name="微软雅黑" size="14" />
 	<Font id="1" name="微软雅黑" size="14" />
 	
 	
-	<ShangpinFoodItem name="shangpin_fooditem" bkcolor="#FFFFFFFF" padding="0,0,5,5">
+	<ShangpinFoodItem name="shangpin_fooditem" bkcolor="#FFFFFFFF" padding="0,0,0,0" width="130" height="90">
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="foodname" width="130" height="64" wordbreak="true" endellipsis="true"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
 		<Label name="price" height="26" font="daindan_price" textcolor="#FFFF7F50" align="left"></Label>
 			
 			

BIN
bin/Win32/Release/zhipuzi_pos_windows/DuiLib.dll


BIN
dll/debug/DuiLib_d.dll


BIN
dll/release/DuiLib.dll


+ 6 - 0
zhipuzi_pos_windows/ai/SQLiteVecManager.cpp

@@ -170,6 +170,12 @@ std::vector<FeatureRecord> SQLiteVecManager::searchSimilarVectors(const std::vec
 		float distance = static_cast<float>(sqlite3_column_double(stmt, 4));
 		float distance = static_cast<float>(sqlite3_column_double(stmt, 4));
 		float similarity = distanceToSimilarity(distance);
 		float similarity = distanceToSimilarity(distance);
 
 
+		if (similarity < 0.8)
+		{
+			//相似度小于0.8的不要
+			continue;
+		}
+
 		FeatureRecord record;
 		FeatureRecord record;
 		record.foodId = food_id ? food_id : "";
 		record.foodId = food_id ? food_id : "";
 		record.foodName = food_name ? food_name : "";
 		record.foodName = food_name ? food_name : "";

+ 5 - 131
zhipuzi_pos_windows/ai/YoloFeatureManager.cpp

@@ -124,6 +124,8 @@ std::vector<float> YoloFeatureManager::extractFeatures(const std::string & image
 
 
 std::vector<float> YoloFeatureManager::extractFeatures(cv::Mat& image)
 std::vector<float> YoloFeatureManager::extractFeatures(cv::Mat& image)
 {
 {
+	std::lock_guard<std::mutex> lock(m_mutex);
+
 	try
 	try
 	{
 	{
 		auto time_1 = std::chrono::high_resolution_clock::now();
 		auto time_1 = std::chrono::high_resolution_clock::now();
@@ -141,7 +143,7 @@ std::vector<float> YoloFeatureManager::extractFeatures(cv::Mat& image)
 		auto time_2 = std::chrono::high_resolution_clock::now();
 		auto time_2 = std::chrono::high_resolution_clock::now();
 
 
 		//获取模型的所有层名称(调试用)
 		//获取模型的所有层名称(调试用)
-		//std::vector<cv::String> layerNames = net.getLayerNames();
+		std::vector<cv::String> layerNames = net.getLayerNames();
 
 
 		// 获取Flatten层输出(yolo26s-cls的Flatten层名称为 "onnx_node!/model.10/Flatten",这是GAP后分类头前的一层)'
 		// 获取Flatten层输出(yolo26s-cls的Flatten层名称为 "onnx_node!/model.10/Flatten",这是GAP后分类头前的一层)'
 		// GAP层是onnx_node!/model.10/pool/GlobalAveragePool
 		// GAP层是onnx_node!/model.10/pool/GlobalAveragePool
@@ -195,138 +197,10 @@ std::vector<float> YoloFeatureManager::extractFeatures(cv::Mat& image)
 	}
 	}
 }
 }
 
 
-void YoloFeatureManager::Detection(const std::string & imagePath)
-{
-	cv::Mat image = cv::imread(imagePath);
-	if (image.empty())
-	{
-		throw std::runtime_error("Could not load image: " + imagePath);
-	}
-
-	// 构造输入blob(图像预处理)
-	// 参数说明:输入图像、缩放因子、输入尺寸、均值归一化、是否交换RB通道、是否裁剪
-	cv::Mat blob;
-	cv::dnn::blobFromImage(image, blob, 1.0 / 255, cv::Size(inputWidth, inputHeight), cv::Scalar(0, 0, 0), true, false);
-
-	// -------------------------- 4. 模型推理 --------------------------
-	// 设置网络输入
-	net.setInput(blob);
-
-	// 获取输出层名称
-	std::vector<std::string> outLayerNames = net.getUnconnectedOutLayersNames();
-
-	// 前向推理
-	std::vector<cv::Mat> outs;
-	net.forward(outs, outLayerNames);
-
-	// -------------------------- 5. 解析推理结果 --------------------------
-	std::vector<cv::Rect> boxes;        // 检测框
-	std::vector<int> classIds;      // 类别ID
-	std::vector<float> confidences; // 置信度
-
-	// 遍历所有输出层的结果
-	for (const cv::Mat & out : outs)
-	{
-		float * data = (float *)out.data;
-		// 遍历每个检测结果
-		for (int i = 0; i < out.rows; i++, data += out.cols)
-		{
-			// 获取类别置信度
-			cv::Mat scores = out.row(i).colRange(5, out.cols);
-			cv::Point classIdPoint;
-			double confidence;
-
-			// 找到最大置信度对应的类别
-			cv::minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);
-
-			// 过滤低置信度结果
-			if (confidence > CONF_THRESHOLD)
-			{
-				// 解析检测框坐标(YOLO输出的是相对坐标,需转换为绝对坐标)
-				int centerX = (int)(data[0] * image.cols);
-				int centerY = (int)(data[1] * image.rows);
-				int width = (int)(data[2] * image.cols);
-				int height = (int)(data[3] * image.rows);
-
-				// 计算检测框左上角坐标
-				int left = centerX - width / 2;
-				int top = centerY - height / 2;
-
-				// 保存结果
-				boxes.push_back(cv::Rect(left, top, width, height));
-				classIds.push_back(classIdPoint.x);
-				confidences.push_back((float)confidence);
-			}
-		}
-	}
-
-	// -------------------------- 6. 非极大值抑制(NMS) --------------------------
-	std::vector<int> indices;
-	cv::dnn::NMSBoxes(boxes, confidences, CONF_THRESHOLD, NMS_THRESHOLD, indices);
-
-	// 提取NMS后的结果
-	std::vector<cv::Rect> finalBoxes;
-	std::vector<int> finalClassIds;
-	std::vector<float> finalConfidences;
-	for (int idx : indices)
-	{
-		finalBoxes.push_back(boxes[idx]);
-		finalClassIds.push_back(classIds[idx]);
-		finalConfidences.push_back(confidences[idx]);
-	}
-
-	// -------------------------- 7. 绘制并显示结果 --------------------------
-	drawDetection(image, finalBoxes, finalClassIds, finalConfidences);
-
-	// 显示检测结果
-	cv::imshow("YOLO Detection Result", image);
-	// 保存检测结果
-	cv::imwrite("result.jpg", image);
-
-	cv::waitKey(0);
-	cv::destroyAllWindows();
-}
-
-// 绘制检测结果
-void YoloFeatureManager::drawDetection(cv::Mat & img, const std::vector<cv::Rect> & boxes, const std::vector<int> & classIds,
-	const std::vector<float> & confidences)
-{
-	// 生成随机颜色(每个类别一种颜色)
-	std::vector<cv::Scalar> colors;
-	srand(time(0));
-	for (std::size_t i = 0; i < FRUIT_VEGETABLE_COUNT; i++)
-	{
-		int r = rand() % 256;
-		int g = rand() % 256;
-		int b = rand() % 256;
-		colors.push_back(cv::Scalar(r, g, b));
-	}
-
-	// 绘制每个检测框
-	for (size_t i = 0; i < boxes.size(); i++)
-	{
-		cv::Rect box = boxes[i];
-		// 绘制矩形框
-		cv::rectangle(img, box, colors[classIds[i]], 2);
-
-		// 构造标签文本(类别 + 置信度)
-		std::string label = FRUIT_VEGETABLE_NAMES[classIds[i]] + ": " + std::to_string(confidences[i]).substr(0, 4);
-		int baseLine;
-		cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
-
-		// 绘制标签背景
-		cv::rectangle(img, cv::Point(box.x, box.y - labelSize.height),
-			cv::Point(box.x + labelSize.width, box.y + baseLine),
-			colors[classIds[i]], cv::FILLED);
-
-		// 绘制标签文本
-		cv::putText(img, label, cv::Point(box.x, box.y), cv::FONT_HERSHEY_SIMPLEX,
-			0.5, cv::Scalar(255, 255, 255), 1);
-	}
-}
-
 std::string YoloFeatureManager::Class(cv::Mat & image)
 std::string YoloFeatureManager::Class(cv::Mat & image)
 {
 {
+	std::lock_guard<std::mutex> lock(m_mutex);
+
 	try
 	try
 	{
 	{
 		std::string className = "";
 		std::string className = "";

+ 2 - 7
zhipuzi_pos_windows/ai/YoloFeatureManager.h

@@ -38,13 +38,6 @@ public:
 
 
 	std::vector<float> extractFeatures(cv::Mat& image);
 	std::vector<float> extractFeatures(cv::Mat& image);
 
 
-	// 执行探测
-	void Detection(const std::string& imagePath);
-
-	// 绘制探测结果
-	void YoloFeatureManager::drawDetection(cv::Mat& img, const std::vector<cv::Rect>& boxes, const std::vector<int>& classIds,
-		const std::vector<float>& confidences);
-
 	//根据摄像头读取的帧,识别出对应类别的name(英文的)
 	//根据摄像头读取的帧,识别出对应类别的name(英文的)
 	std::string Class(cv::Mat& image);
 	std::string Class(cv::Mat& image);
 
 
@@ -56,4 +49,6 @@ private:
 	std::string getClassName(std::size_t classId) const;
 	std::string getClassName(std::size_t classId) const;
 
 
 	void drawChineseText(cv::Mat & img, const wchar_t * text, cv::Point pos, cv::Scalar color, int fontSize);
 	void drawChineseText(cv::Mat & img, const wchar_t * text, cv::Point pos, cv::Scalar color, int fontSize);
+
+	std::mutex m_mutex; // 互斥锁,保护模型加载和推理过程
 };
 };

+ 2 - 2
zhipuzi_pos_windows/page/CAIxuexiPageUI.cpp

@@ -165,7 +165,7 @@ void CAIxuexiPageUI::UpdateFoodtypePos()
 	}
 	}
 
 
 	//根据宽度计算每行显示的数量
 	//根据宽度计算每行显示的数量
-	int nMeihangNum = (nWidth - 321) / 140;
+	int nMeihangNum = (nWidth - 422) / 140;
 
 
 	int num = 0;
 	int num = 0;
 
 
@@ -640,7 +640,7 @@ void CAIxuexiPageUI::DoXuexi()
 
 
 	//第二步把这个图片的特征向量提取出来,保存到数据库里,关联到当前选中的商品上
 	//第二步把这个图片的特征向量提取出来,保存到数据库里,关联到当前选中的商品上
 	std::cout << "开始提取图库图片特征..." << std::endl;
 	std::cout << "开始提取图库图片特征..." << std::endl;
-	std::vector<float> features = YoloFeatureManager::GetInstance()->extractFeatures(s_file_save_path);
+	std::vector<float> features = YoloFeatureManager::GetInstance()->extractFeatures(img);
 	if (!features.empty())
 	if (!features.empty())
 	{
 	{
 		std::string sName = m_cur_click_food_item->GetFoodInfo().name;
 		std::string sName = m_cur_click_food_item->GetFoodInfo().name;

+ 0 - 11
zhipuzi_pos_windows/page/CDiandanPageUI.cpp

@@ -63,17 +63,6 @@ void CDiandanPageUI::InitShow()
 
 
 		m_is_zidingyizhifu_init = true;
 		m_is_zidingyizhifu_init = true;
 	}
 	}
-
-	//根据AI识别的设置,启动或者暂停AI识别【在进入点单页面的时候设置刚好合适】
-	std::string is_ai_shibie = CSetting::GetInstance()->GetParam("setting_is_ai_recognition_open");
-	if (is_ai_shibie == "1")
-	{
-		CDiandanAIShibieWorker::GetInstance()->StartAIShibie();
-	}
-	else
-	{
-		CDiandanAIShibieWorker::GetInstance()->StopAIShibie();
-	}
 }
 }
 
 
 void CDiandanPageUI::RefreshShow()
 void CDiandanPageUI::RefreshShow()

+ 1 - 1
zhipuzi_pos_windows/page/CShangpinPageUI.cpp

@@ -103,7 +103,7 @@ void CShangpinPageUI::UpdateFoodtypePos()
 	}
 	}
 
 
 	//根据宽度计算每行显示的数量
 	//根据宽度计算每行显示的数量
-	int nMeihangNum = (nWidth - 321) / 140;
+	int nMeihangNum = (nWidth - 351) / 140;
 
 
 	int num = 0;
 	int num = 0;
 
 

+ 11 - 0
zhipuzi_pos_windows/wnd/CMainWnd.cpp

@@ -176,6 +176,17 @@ void CMainWnd::SwitchPage(MainPageName name, bool is_init_show)
 	{
 	{
 		pChildContainer->InitShow();
 		pChildContainer->InitShow();
 	}
 	}
+
+	//根据AI识别的设置,启动或者暂停AI识别【在进入点单页面的时候设置刚好合适】
+	std::string is_ai_shibie = CSetting::GetInstance()->GetParam("setting_is_ai_recognition_open");
+	if (is_ai_shibie == "1" && m_curPageName == CMainWnd::DIANDAN)
+	{
+		CDiandanAIShibieWorker::GetInstance()->StartAIShibie();
+	}
+	else
+	{
+		CDiandanAIShibieWorker::GetInstance()->StopAIShibie();
+	}
 }
 }
 
 
 LRESULT CMainWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 LRESULT CMainWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)

+ 71 - 24
zhipuzi_pos_windows/worker/CDiandanAIShibieWorker.cpp

@@ -8,7 +8,7 @@
 
 
 CDiandanAIShibieWorker::CDiandanAIShibieWorker()
 CDiandanAIShibieWorker::CDiandanAIShibieWorker()
 {
 {
-
+	
 }
 }
 
 
 CDiandanAIShibieWorker::~CDiandanAIShibieWorker()
 CDiandanAIShibieWorker::~CDiandanAIShibieWorker()
@@ -35,8 +35,6 @@ void CDiandanAIShibieWorker::StopWork()
 
 
 void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 {
 {
-	long int threadId = GetCurrentThreadId();
-
 	while (m_is_work == true)
 	while (m_is_work == true)
 	{
 	{
 		try
 		try
@@ -44,6 +42,17 @@ void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 			if (m_is_ai_shibie == false)
 			if (m_is_ai_shibie == false)
 			{
 			{
 				//说明没开启AI识别,就等着
 				//说明没开启AI识别,就等着
+				if (m_ai_shibie_foodname != "Unknown")
+				{
+					m_ai_shibie_foodname = "Unknown";
+
+					//主线程里面去处理界面刷新
+					if (m_hwnd != NULL)
+					{
+						::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+					}
+				}
+
 				Sleep(2000);
 				Sleep(2000);
 
 
 				continue;
 				continue;
@@ -53,18 +62,38 @@ void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 			if (weight < -0.01)
 			if (weight < -0.01)
 			{
 			{
 				//说明没有重量,没放东西到秤上面,那么就不识别
 				//说明没有重量,没放东西到秤上面,那么就不识别
+				if (m_ai_shibie_foodname != "Unknown")
+				{
+					m_ai_shibie_foodname = "Unknown";
+
+					//主线程里面去处理界面刷新
+					if (m_hwnd != NULL)
+					{
+						::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+					}
+				}
+
 				Sleep(100);
 				Sleep(100);
 
 
 				continue;
 				continue;
 			}
 			}
 
 
-			auto time_1 = std::chrono::high_resolution_clock::now();
-
 			cv::Mat image;
 			cv::Mat image;
 			CVideoCaptureWorker::GetInstance()->GetFrame(image);
 			CVideoCaptureWorker::GetInstance()->GetFrame(image);
 			if (image.empty())
 			if (image.empty())
 			{
 			{
-				//DEBUG_LOG("从摄像头获取帧失败");
+				//从摄像头获取帧失败
+				if (m_ai_shibie_foodname != "Unknown")
+				{
+					m_ai_shibie_foodname = "Unknown";
+
+					//主线程里面去处理界面刷新
+					if (m_hwnd != NULL)
+					{
+						::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+					}
+				}
+
 				Sleep(2000);
 				Sleep(2000);
 
 
 				continue;
 				continue;
@@ -76,11 +105,18 @@ void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 				std::cout << "检测到类别: " << m_ai_shibie_foodname << std::endl;
 				std::cout << "检测到类别: " << m_ai_shibie_foodname << std::endl;
 
 
 				m_ai_shibie_foodname = CLewaimaiString::ANSIToUTF8(m_ai_shibie_foodname);
 				m_ai_shibie_foodname = CLewaimaiString::ANSIToUTF8(m_ai_shibie_foodname);
+
+				//主线程里面去处理界面刷新
+				if (m_hwnd != NULL)
+				{
+					::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+				}
+
+				Sleep(30);
+				continue;
 			}
 			}
 			else
 			else
 			{
 			{
-				std::cout << "未检测到任何类别。" << std::endl;
-
 				//开始调用向量数据库检索
 				//开始调用向量数据库检索
 				if (SQLiteVecManager::GetInstance()->getFeatureCount() > 0)
 				if (SQLiteVecManager::GetInstance()->getFeatureCount() > 0)
 				{
 				{
@@ -114,33 +150,44 @@ void CDiandanAIShibieWorker::HandleDiandanAIShibie()
 
 
 							//UTF8格式,sqlite里面存的都是UTF8格式的字符串
 							//UTF8格式,sqlite里面存的都是UTF8格式的字符串
 							m_ai_shibie_foodname = newFood.name;
 							m_ai_shibie_foodname = newFood.name;
+
+							//主线程里面去处理界面刷新
+							if (m_hwnd != NULL)
+							{
+								::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+							}
+
+							Sleep(30);
+							continue;
 						}
 						}
 					}
 					}
 					else
 					else
 					{
 					{
-						std::cout << "向量数据库中没有相似的特征。" << std::endl;
-						Sleep(100);
+						//向量数据库中没有相似的特征						
+						m_ai_shibie_foodname = "Unknown";
 
 
-						continue;
+						//主线程里面去处理界面刷新
+						if (m_hwnd != NULL)
+						{
+							::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+						}
+
+						Sleep(100);
 					}
 					}
 				}
 				}
 				else
 				else
 				{
 				{
-					std::cout << "向量数据库中没有任何特征。" << std::endl;
-					Sleep(100);
-					continue;
-				}
-			}
-
-			auto time_2 = std::chrono::high_resolution_clock::now();
+					//向量数据库中没有任何特征					
+					m_ai_shibie_foodname = "Unknown";
 
 
-			auto duration_1 = std::chrono::duration_cast<std::chrono::milliseconds>(time_2 - time_1);
-			std::wstring msg = L"all time: " + std::to_wstring(duration_1.count()) + L" 毫秒";
+					//主线程里面去处理界面刷新
+					if (m_hwnd != NULL)
+					{
+						::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+					}
 
 
-			//主线程里面去处理界面刷新
-			if (m_hwnd != NULL)
-			{
-				::PostMessage(m_hwnd, WM_AI_RECOGNITION_SUCCESS, 0, 0);
+					Sleep(100);
+				}
 			}
 			}
 		}
 		}
 		catch (const std::exception& e)
 		catch (const std::exception& e)