张洋 19 часов назад
Родитель
Сommit
a0b24d3aa5

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


+ 2 - 2
zhipuzi_pos_windows/ai/SQLiteVecManager.cpp

@@ -97,7 +97,7 @@ bool SQLiteVecManager::addFeatureVector(const std::vector<float> & features, con
 		std::string err = sqlite3_errmsg(db);
 		std::string err = sqlite3_errmsg(db);
 		std::cerr << "Failed to insert feature vector: " << err << std::endl;
 		std::cerr << "Failed to insert feature vector: " << err << std::endl;
 		sqlite3_finalize(stmt);
 		sqlite3_finalize(stmt);
-		return -1;
+		return false;
 	}
 	}
 
 
 	sqlite3_finalize(stmt);
 	sqlite3_finalize(stmt);
@@ -195,7 +195,7 @@ std::string SQLiteVecManager::vectorToBlob(const std::vector<float> & vec)
 {
 {
 	std::string vecStr;
 	std::string vecStr;
 
 
-	for (int i = 0; i < vec.size(); i++) {
+	for (std::size_t i = 0; i < vec.size(); i++) {
 		vecStr += std::to_string(vec[i]);
 		vecStr += std::to_string(vec[i]);
 		if (i != vec.size() - 1) {
 		if (i != vec.size() - 1) {
 			vecStr += ",";
 			vecStr += ",";

+ 261 - 0
zhipuzi_pos_windows/ai/YoloClassName.h

@@ -0,0 +1,261 @@
+#pragma once
+
+#include <string>
+#include <unordered_map>
+
+// 果蔬名称常量数组(索引对应英文名称)
+// 注释格式:[索引] 英文名称 // 中文名称
+const std::string FRUIT_VEGETABLE_NAMES[] = {
+    "apple_akosu",          // 0: 阿克苏苹果
+    "apple_gala",           // 1: 嘎啦苹果
+    "apple_green",          // 2: 青苹果
+    "apple_hua_niu",        // 3: 花牛苹果
+    "apple_red_fuji",       // 4: 红富士苹果
+    "apricot",              // 5: 杏
+    "asparagus",            // 6: 芦笋
+    "avocado",              // 7: 牛油果
+    "banana",               // 8: 香蕉
+    "bamboo_shoot",         // 9: 竹笋
+    "baby_cabbage",         // 10: 娃娃菜
+    "bean_green",           // 11: 四季豆
+    "bitter_gourd",         // 12: 苦瓜
+    "blueberry",            // 13: 蓝莓
+    "bokchoy",              // 14: 上海青
+    "broccoli",             // 15: 西兰花
+    "cabbage_chinese",      // 16: 大白菜
+    "cabbage_purple",       // 17: 紫甘蓝
+    "cabbage_round",        // 18: 圆白菜
+    "cabbage_small",        // 19: 小白菜
+    "cantaloupe",           // 20: 哈密瓜
+    "cantaloupe_nettle",    // 21: 网纹瓜
+    "cantaloupe_xizhou",    // 22: 西州蜜
+    "carrot",               // 23: 胡萝卜
+    "carrot_yellow",        // 24: 黄胡萝卜
+    "cauliflower",          // 25: 白花菜
+    "caixin",               // 26: 菜心
+    "celery",               // 27: 芹菜
+    "cherry",               // 28: 樱桃
+    "cherry_big",           // 29: 车厘子
+    "chili_small",          // 30: 小米辣
+    "chinese_yam",          // 31: 山药
+    "chives",               // 32: 韭菜
+    "coriander",            // 33: 香菜
+    "corn",                 // 34: 玉米
+    "cowpea",               // 35: 豇豆
+    "cucumber",             // 36: 黄瓜
+    "cucumber_fruit",       // 37: 水果黄瓜
+    "cucumber_white",       // 38: 白玉黄瓜
+    "durian",               // 39: 榴莲
+    "dragonfruit_red",      // 40: 红心火龙果
+    "dragonfruit_white",    // 41: 白心火龙果
+    "eggplant_long",        // 42: 长茄子
+    "eggplant_round",       // 43: 圆茄子
+    "garlic",               // 44: 大蒜
+    "garlic_scape",         // 45: 蒜苔
+    "ginger",               // 46: 生姜
+    "grape_black",          // 47: 夏黑
+    "grape_green",          // 48: 青提
+    "grape_kyoho",          // 49: 巨峰葡萄
+    "grape_red",            // 50: 红提
+    "grape_seedless",       // 51: 无籽葡萄
+    "grape_shine",          // 52: 阳光玫瑰
+    "grapefruit",           // 53: 西柚
+    "jujube_winter",        // 54: 冬枣
+    "kiwi_green",           // 55: 绿心猕猴桃
+    "kiwi_red",             // 56: 红心猕猴桃
+    "lemon",                // 57: 柠檬
+    "lime",                // 58: 青柠
+    "lettuce",              // 59: 生菜
+    "lettuce_romaine",      // 60: 罗马生菜
+    "litchi",               // 61: 荔枝
+    "loofah",               // 62: 丝瓜
+    "longan",               // 63: 龙眼
+    "lotus_root",           // 64: 莲藕
+    "mango_golden",         // 65: 金煌芒
+    "mango_guifei",         // 66: 贵妃芒
+    "mango_small",          // 67: 小台农芒果
+    "mangosteen",           // 68: 山竹
+    "muskmelon_common",     // 69: 香瓜
+    "muskmelon_green",      // 70: 绿宝甜瓜
+    "muskmelon_horn",       // 71: 羊角蜜
+    "mushroom_enoki",       // 72: 金针菇
+    "mushroom_king",        // 73: 杏鲍菇
+    "mushroom_oyster",      // 74: 平菇
+    "mushroom_shiitake",    // 75: 香菇
+    "okra",                 // 76: 秋葵
+    "oil_vegetable",        // 77: 油麦菜
+    "onion_purple",         // 78: 紫洋葱
+    "onion_white",          // 79: 白洋葱
+    "orange_mandarin",      // 80: 蜜橘
+    "orange_navel",         // 81: 脐橙
+    "orange_papa",          // 82: 耙耙柑
+    "orange_tangerine",     // 83: 砂糖橘
+    "orange_ugly",          // 84: 丑橘
+    "orange_wogan",         // 85: 沃柑
+    "papaya",               // 86: 木瓜
+    "peach_flat",           // 87: 蟠桃
+    "peach_honey",          // 88: 水蜜桃
+    "peach_nectarine",      // 89: 油桃
+    "peach_yellow",         // 90: 黄桃
+    "pear_kuerle",          // 91: 库尔勒香梨
+    "pear_qiuyue",          // 92: 秋月梨
+    "pear_snow",            // 93: 雪梨
+    "pear_ya",              // 94: 鸭梨
+    "pepper_bell_green",    // 95: 绿彩椒
+    "pepper_bell_red",      // 96: 红彩椒
+    "pepper_bell_yellow",   // 97: 黄彩椒
+    "pea",                  // 98: 豌豆
+    "pineapple",            // 99: 菠萝
+    "pineapple_yellow",     // 100: 凤梨
+    "plum",                 // 101: 李子
+    "plum_black",           // 102: 黑布林
+    "pomegranate",          // 103: 石榴
+    "potato",               // 104: 土豆
+    "pumpkin",              // 105: 南瓜
+    "pumpkin_baby",         // 106: 贝贝南瓜
+    "purple_potato",        // 107: 紫薯
+    "radish_cherry",        // 108: 樱桃萝卜
+    "radish_red",           // 109: 红萝卜
+    "radish_white",         // 110: 白萝卜
+    "spinach",              // 111: 菠菜
+    "strawberry",           // 112: 草莓
+    "sweet_potato",         // 113: 红薯
+    "tomato_big",           // 114: 大番茄
+    "tomato_cherry",        // 115: 圣女果
+    "tomato_qianxi",        // 116: 千禧果
+    "wax_gourd",            // 117: 冬瓜
+    "watermelon",           // 118: 西瓜
+    "watermelon_8424",      // 119: 8424西瓜
+    "watermelon_black_beauty", // 120: 黑美人西瓜
+    "watermelon_qilin",     // 121: 麒麟西瓜
+    "wood_ear",             // 122: 木耳
+    "zucchini"              // 123: 西葫芦
+};
+
+// 果蔬英文名称 -> 中文名称 映射表(哈希表,查询效率O(1))
+const std::unordered_map<std::string, std::string> FRUIT_VEGETABLE_CN_MAP = {
+    {"apple_akosu", "阿克苏苹果"},
+    {"apple_gala", "嘎啦苹果"},
+    {"apple_green", "青苹果"},
+    {"apple_hua_niu", "花牛苹果"},
+    {"apple_red_fuji", "红富士苹果"},
+    {"apricot", "杏"},
+    {"asparagus", "芦笋"},
+    {"avocado", "牛油果"},
+    {"banana", "香蕉"},
+    {"bamboo_shoot", "竹笋"},
+    {"baby_cabbage", "娃娃菜"},
+    {"bean_green", "四季豆"},
+    {"bitter_gourd", "苦瓜"},
+    {"blueberry", "蓝莓"},
+    {"bokchoy", "上海青"},
+    {"broccoli", "西兰花"},
+    {"cabbage_chinese", "大白菜"},
+    {"cabbage_purple", "紫甘蓝"},
+    {"cabbage_round", "圆白菜"},
+    {"cabbage_small", "小白菜"},
+    {"cantaloupe", "哈密瓜"},
+    {"cantaloupe_nettle", "网纹瓜"},
+    {"cantaloupe_xizhou", "西州蜜"},
+    {"carrot", "胡萝卜"},
+    {"carrot_yellow", "黄胡萝卜"},
+    {"cauliflower", "白花菜"},
+    {"caixin", "菜心"},
+    {"celery", "芹菜"},
+    {"cherry", "樱桃"},
+    {"cherry_big", "车厘子"},
+    {"chili_small", "小米辣"},
+    {"chinese_yam", "山药"},
+    {"chives", "韭菜"},
+    {"coriander", "香菜"},
+    {"corn", "玉米"},
+    {"cowpea", "豇豆"},
+    {"cucumber", "黄瓜"},
+    {"cucumber_fruit", "水果黄瓜"},
+    {"cucumber_white", "白玉黄瓜"},
+    {"durian", "榴莲"},
+    {"dragonfruit_red", "红心火龙果"},
+    {"dragonfruit_white", "白心火龙果"},
+    {"eggplant_long", "长茄子"},
+    {"eggplant_round", "圆茄子"},
+    {"garlic", "大蒜"},
+    {"garlic_scape", "蒜苔"},
+    {"ginger", "生姜"},
+    {"grape_black", "夏黑"},
+    {"grape_green", "青提"},
+    {"grape_kyoho", "巨峰葡萄"},
+    {"grape_red", "红提"},
+    {"grape_seedless", "无籽葡萄"},
+    {"grape_shine", "阳光玫瑰"},
+    {"grapefruit", "西柚"},
+    {"jujube_winter", "冬枣"},
+    {"kiwi_green", "绿心猕猴桃"},
+    {"kiwi_red", "红心猕猴桃"},
+    {"lemon", "柠檬"},
+    {"lime", "青柠"},
+    {"lettuce", "生菜"},
+    {"lettuce_romaine", "罗马生菜"},
+    {"litchi", "荔枝"},
+    {"loofah", "丝瓜"},
+    {"longan", "龙眼"},
+    {"lotus_root", "莲藕"},
+    {"mango_golden", "金煌芒"},
+    {"mango_guifei", "贵妃芒"},
+    {"mango_small", "小台农芒果"},
+    {"mangosteen", "山竹"},
+    {"muskmelon_common", "香瓜"},
+    {"muskmelon_green", "绿宝甜瓜"},
+    {"muskmelon_horn", "羊角蜜"},
+    {"mushroom_enoki", "金针菇"},
+    {"mushroom_king", "杏鲍菇"},
+    {"mushroom_oyster", "平菇"},
+    {"mushroom_shiitake", "香菇"},
+    {"okra", "秋葵"},
+    {"oil_vegetable", "油麦菜"},
+    {"onion_purple", "紫洋葱"},
+    {"onion_white", "白洋葱"},
+    {"orange_mandarin", "蜜橘"},
+    {"orange_navel", "脐橙"},
+    {"orange_papa", "耙耙柑"},
+    {"orange_tangerine", "砂糖橘"},
+    {"orange_ugly", "丑橘"},
+    {"orange_wogan", "沃柑"},
+    {"papaya", "木瓜"},
+    {"peach_flat", "蟠桃"},
+    {"peach_honey", "水蜜桃"},
+    {"peach_nectarine", "油桃"},
+    {"peach_yellow", "黄桃"},
+    {"pear_kuerle", "库尔勒香梨"},
+    {"pear_qiuyue", "秋月梨"},
+    {"pear_snow", "雪梨"},
+    {"pear_ya", "鸭梨"},
+    {"pepper_bell_green", "绿彩椒"},
+    {"pepper_bell_red", "红彩椒"},
+    {"pepper_bell_yellow", "黄彩椒"},
+    {"pea", "豌豆"},
+    {"pineapple", "菠萝"},
+    {"pineapple_yellow", "凤梨"},
+    {"plum", "李子"},
+    {"plum_black", "黑布林"},
+    {"pomegranate", "石榴"},
+    {"potato", "土豆"},
+    {"pumpkin", "南瓜"},
+    {"pumpkin_baby", "贝贝南瓜"},
+    {"purple_potato", "紫薯"},
+    {"radish_cherry", "樱桃萝卜"},
+    {"radish_red", "红萝卜"},
+    {"radish_white", "白萝卜"},
+    {"spinach", "菠菜"},
+    {"strawberry", "草莓"},
+    {"sweet_potato", "红薯"},
+    {"tomato_big", "大番茄"},
+    {"tomato_cherry", "圣女果"},
+    {"tomato_qianxi", "千禧果"},
+    {"wax_gourd", "冬瓜"},
+    {"watermelon", "西瓜"},
+    {"watermelon_8424", "8424西瓜"},
+    {"watermelon_black_beauty", "黑美人西瓜"},
+    {"watermelon_qilin", "麒麟西瓜"},
+    {"wood_ear", "木耳"},
+    {"zucchini", "西葫芦"}
+};

+ 50 - 19
zhipuzi_pos_windows/ai/YoloFeatureManager.cpp

@@ -10,33 +10,47 @@
 
 
 #include "../tool/debuglog.h"
 #include "../tool/debuglog.h"
 
 
+#include "../worker/CVideoCaptureWorker.h"
+
+#include "YoloClassName.h"
+
 YoloFeatureManager::YoloFeatureManager()
 YoloFeatureManager::YoloFeatureManager()
 {
 {
 }
 }
 
 
-void YoloFeatureManager::loadModel(const std::string & modelPath, const std::string & classesPath)
+void YoloFeatureManager::loadModel(const std::string & modelPath)
 {
 {
 	inputWidth = 448;
 	inputWidth = 448;
 	inputHeight = 448;
 	inputHeight = 448;
 
 
 	net = cv::dnn::readNetFromONNX(modelPath);
 	net = cv::dnn::readNetFromONNX(modelPath);
-	loadClassNames(classesPath);
 
 
 	CONF_THRESHOLD = 0.5f; // 可以根据需要调整置信度阈值
 	CONF_THRESHOLD = 0.5f; // 可以根据需要调整置信度阈值
 	NMS_THRESHOLD = 0.4f;  // 可以根据需要调整NMS阈值
 	NMS_THRESHOLD = 0.4f;  // 可以根据需要调整NMS阈值
+
+	FRUIT_VEGETABLE_COUNT = sizeof(FRUIT_VEGETABLE_NAMES) / sizeof(FRUIT_VEGETABLE_NAMES[0]);
 }
 }
 
 
-void YoloFeatureManager::loadClassNames(const std::string & file)
+//	获取类别名称
+std::string YoloFeatureManager::getClassName(std::size_t classId) const
 {
 {
-	//先清空
-	classNames.clear();
-
-	std::ifstream ifs(file);
-	std::string line;
-	while (std::getline(ifs, line))
+	if (classId >= 0 && classId < FRUIT_VEGETABLE_COUNT)
 	{
 	{
-		classNames.push_back(line);
+		std::string englishName = FRUIT_VEGETABLE_NAMES[classId];
+		
+		// 这里可以添加一个映射表,将英文名称映射到中文名称
+		auto it = FRUIT_VEGETABLE_CN_MAP.find(englishName);
+		if (it != FRUIT_VEGETABLE_CN_MAP.end()) 
+		{
+			return it->second; // 找到则返回中文名称
+		}
+		else 
+		{
+			return "Unknown"; // 未找到则返回默认值
+		}
 	}
 	}
+
+	return "Unknown";
 }
 }
 
 
 std::vector<float> YoloFeatureManager::extractFeatures(const std::string& imagePath)
 std::vector<float> YoloFeatureManager::extractFeatures(const std::string& imagePath)
@@ -189,7 +203,7 @@ void YoloFeatureManager::Detection(const std::string& imagePath)
 	}
 	}
 
 
 	// -------------------------- 7. 绘制并显示结果 --------------------------
 	// -------------------------- 7. 绘制并显示结果 --------------------------
-	drawDetection(image, finalBoxes, finalClassIds, finalConfidences, classNames);
+	drawDetection(image, finalBoxes, finalClassIds, finalConfidences);
 
 
 	// 显示检测结果
 	// 显示检测结果
 	cv::imshow("YOLO Detection Result", image);
 	cv::imshow("YOLO Detection Result", image);
@@ -202,11 +216,12 @@ void YoloFeatureManager::Detection(const std::string& imagePath)
 
 
 // 绘制检测结果
 // 绘制检测结果
 void YoloFeatureManager::drawDetection(cv::Mat& img, const std::vector<cv::Rect>& boxes, const std::vector<int>& classIds,
 void YoloFeatureManager::drawDetection(cv::Mat& img, const std::vector<cv::Rect>& boxes, const std::vector<int>& classIds,
-	const std::vector<float>& confidences, const std::vector<std::string>& classNames) {
+	const std::vector<float>& confidences) 
+{
 	// 生成随机颜色(每个类别一种颜色)
 	// 生成随机颜色(每个类别一种颜色)
 	std::vector<cv::Scalar> colors;
 	std::vector<cv::Scalar> colors;
 	srand(time(0));
 	srand(time(0));
-	for (std::size_t i = 0; i < classNames.size(); i++) {
+	for (std::size_t i = 0; i < FRUIT_VEGETABLE_COUNT; i++) {
 		int r = rand() % 256;
 		int r = rand() % 256;
 		int g = rand() % 256;
 		int g = rand() % 256;
 		int b = rand() % 256;
 		int b = rand() % 256;
@@ -220,7 +235,7 @@ void YoloFeatureManager::drawDetection(cv::Mat& img, const std::vector<cv::Rect>
 		cv::rectangle(img, box, colors[classIds[i]], 2);
 		cv::rectangle(img, box, colors[classIds[i]], 2);
 
 
 		// 构造标签文本(类别 + 置信度)
 		// 构造标签文本(类别 + 置信度)
-		std::string label = classNames[classIds[i]] + ": " + std::to_string(confidences[i]).substr(0, 4);
+		std::string label = FRUIT_VEGETABLE_NAMES[classIds[i]] + ": " + std::to_string(confidences[i]).substr(0, 4);
 		int baseLine;
 		int baseLine;
 		cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
 		cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
 
 
@@ -255,11 +270,7 @@ std::string YoloFeatureManager::Class(cv::Mat & image)
 	// 只显示置信度高于阈值的结果
 	// 只显示置信度高于阈值的结果
 	if (topConfidence > 0.5)
 	if (topConfidence > 0.5)
 	{
 	{
-		className = classNames[topClassIdx];
-		std::string resultText = className + " : " + std::to_string(round(topConfidence * 10000) / 100) + "%";
-
-		// 在画面上绘制分类结果
-		cv::putText(image, resultText, cv::Point(20, 50), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(0, 255, 0), 3);
+		className = this->getClassName(topClassIdx);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -267,7 +278,27 @@ std::string YoloFeatureManager::Class(cv::Mat & image)
 	}
 	}
 
 
 	// ====================== 显示画面 ======================
 	// ====================== 显示画面 ======================
+	// 在画面上绘制分类结果
+	std::string resultText = className + " : " + std::to_string(round(topConfidence * 10000) / 100) + "%";
+
+	cv::putText(image, resultText, cv::Point(20, 50), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(0, 255, 0), 3);
 	cv::imshow("YOLOv8s-cls 实时图像分类", image);
 	cv::imshow("YOLOv8s-cls 实时图像分类", image);
+	if (cv::waitKey(30) >= 0) ; // 按任意键退出
 
 
 	return className;
 	return className;
+}
+
+std::string YoloFeatureManager::ClassFromVideoCapture()
+{
+	cv::Mat image;
+
+	CVideoCaptureWorker::GetInstance()->GetFrame(image);
+
+	if (image.empty())
+	{
+		DEBUG_LOG("从摄像头获取帧失败");
+		return "Unknown";
+	}
+
+	return Class(image);
 }
 }

+ 7 - 12
zhipuzi_pos_windows/ai/YoloFeatureManager.h

@@ -11,18 +11,18 @@ private:
 	cv::dnn::Net net;
 	cv::dnn::Net net;
 	int inputWidth;
 	int inputWidth;
 	int inputHeight;
 	int inputHeight;
-	std::vector<std::string> classNames;
 
 
 	float CONF_THRESHOLD;
 	float CONF_THRESHOLD;
 	float NMS_THRESHOLD;
 	float NMS_THRESHOLD;
 
 
+	int FRUIT_VEGETABLE_COUNT;
+
 public:
 public:
 	YoloFeatureManager();
 	YoloFeatureManager();
 	~YoloFeatureManager() = default;
 	~YoloFeatureManager() = default;
 
 
 	// 重新加载模型
 	// 重新加载模型
-	void loadModel(const std::string & modelPath, const std::string & classesPath);
-	void loadClassNames(const std::string & file);
+	void loadModel(const std::string & modelPath);
 
 
 	// 提取特征
 	// 提取特征
 	std::vector<float> extractFeatures(const std::string & imagePath);
 	std::vector<float> extractFeatures(const std::string & imagePath);
@@ -32,11 +32,13 @@ public:
 
 
 	// 绘制探测结果
 	// 绘制探测结果
 	void YoloFeatureManager::drawDetection(cv::Mat& img, const std::vector<cv::Rect>& boxes, const std::vector<int>& classIds,
 	void YoloFeatureManager::drawDetection(cv::Mat& img, const std::vector<cv::Rect>& boxes, const std::vector<int>& classIds,
-		const std::vector<float>& confidences, const std::vector<std::string>& classNames);
+		const std::vector<float>& confidences);
 
 
 	//根据摄像头读取的帧,识别出对应类别的name(英文的)
 	//根据摄像头读取的帧,识别出对应类别的name(英文的)
 	std::string Class(cv::Mat& image);
 	std::string Class(cv::Mat& image);
 
 
+	std::string ClassFromVideoCapture();
+
 private:
 private:
 	// 寻找置信度最高的类别
 	// 寻找置信度最高的类别
 	int getTopClass(const cv::Mat & output)
 	int getTopClass(const cv::Mat & output)
@@ -54,12 +56,5 @@ private:
 	}
 	}
 
 
 	//	获取类别名称
 	//	获取类别名称
-	std::string getClassName(std::size_t classId) const
-	{
-		if (classId >= 0 && classId < classNames.size())
-		{
-			return classNames[classId];
-		}
-		return "Unknown";
-	}
+	std::string getClassName(std::size_t classId) const;
 };
 };

+ 1 - 2
zhipuzi_pos_windows/ai/test.cpp

@@ -28,7 +28,6 @@ int AITest()
 		std::string galleryDir = (mainDir.parent_path().parent_path().parent_path().parent_path() /"res"/"images").string();       // 图库目录路径
 		std::string galleryDir = (mainDir.parent_path().parent_path().parent_path().parent_path() /"res"/"images").string();       // 图库目录路径
 
 
 		std::string modelPath = sMainDir + "/ai/best_448.onnx";           // YOLO2026模型路径
 		std::string modelPath = sMainDir + "/ai/best_448.onnx";           // YOLO2026模型路径
-		std::string classesPath = sMainDir + "/ai/cls.names";             // 类别文件路径
 		std::string searchImagePath = sMainDir + "/3.jpg"; // 搜索图片路径
 		std::string searchImagePath = sMainDir + "/3.jpg"; // 搜索图片路径
 
 
 		std::string databasePath = sMainDir + "/image_features.db";     // SQLite数据库路径
 		std::string databasePath = sMainDir + "/image_features.db";     // SQLite数据库路径
@@ -44,7 +43,7 @@ int AITest()
 		// 初始化特征提取器
 		// 初始化特征提取器
 		std::cout << "正在初始化YOLO2026特征提取器..." << std::endl;
 		std::cout << "正在初始化YOLO2026特征提取器..." << std::endl;
 		YoloFeatureManager extractor;
 		YoloFeatureManager extractor;
-		extractor.loadModel(modelPath, classesPath);
+		extractor.loadModel(modelPath);
 
 
 		// 获取图库中的所有图片
 		// 获取图库中的所有图片
 		std::cout << "正在扫描图库中的图片..." << std::endl;
 		std::cout << "正在扫描图库中的图片..." << std::endl;

+ 4 - 1
zhipuzi_pos_windows/helper/define.h

@@ -63,4 +63,7 @@
 #define WM_MYHOTKEY_KUCUN 10814
 #define WM_MYHOTKEY_KUCUN 10814
 #define WM_MYHOTKEY_CAIGOU 10815
 #define WM_MYHOTKEY_CAIGOU 10815
 #define WM_MYHOTKEY_ZHUOTAI 10816
 #define WM_MYHOTKEY_ZHUOTAI 10816
-#define WM_MYHOTKEY_SHOUKUAN 10817
+#define WM_MYHOTKEY_SHOUKUAN 10817
+
+//AI识别相关的
+#define WM_AI_RECOGNITION_SUCCESS 10901

BIN
zhipuzi_pos_windows/page/CDiandanPageUI.cpp


+ 105 - 102
zhipuzi_pos_windows/page/CDiandanPageUI.h

@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
 
 
 #include "../pch/pch.h"
 #include "../pch/pch.h"
 #include "CBasePageUI.h"
 #include "CBasePageUI.h"
@@ -20,248 +20,251 @@ public:
 	CDiandanPageUI();
 	CDiandanPageUI();
 	~CDiandanPageUI();
 	~CDiandanPageUI();
 
 
-	//初始化当前页面的展示,处理默认展示效果,在页面每次被选中加载(注意不是页面创建构造)的时候调用,如果多次选中会多次调用,这里要避免数据重复处理
+	//初始化当前页面的展示,处理默认展示效果,在页面每次被选中加载(注意不是页面创建构造)的时候调用,如果多次选中会多次调用,这里要避免数据重复处理
 	void InitShow();
 	void InitShow();
 
 
-	//收款一个订单成功,准备开始收款第2个订单的时候调用(会多次调度用)
+	//收款一个订单成功,准备开始收款第2个订单的时候调用(会多次调度用)
 	void RefreshShow();
 	void RefreshShow();
 
 
-	//初始化商品分类的显示
+	//鍒濆�鍖栧晢鍝佸垎绫荤殑鏄剧ず
 	void InitFoodtypeShow();
 	void InitFoodtypeShow();
 
 
 	void UpdateFoodtypePos();
 	void UpdateFoodtypePos();
 
 
-	//根据当前选择的分类,刷新商品展示
+	//鏍规嵁褰撳墠閫夋嫨鐨勫垎绫伙紝鍒锋柊鍟嗗搧灞曠ず
 	void InitFoodShow();
 	void InitFoodShow();
 
 
-	//仅仅初始化结算相关的显示(比如折扣、优惠、价格等)
+	//仅仅初始化结算相关的显示(比如折扣、优惠、价格等)
 	void InitJiesuanShow();
 	void InitJiesuanShow();
 
 
-	//初始化结算页面的支付方式展示(仅需要在页面初始化的时候调用一次,这里只添加支付方式,不设置位置)
+	//鍒濆�鍖栫粨绠楅〉闈㈢殑鏀�粯鏂瑰紡灞曠ず(浠呴渶瑕佸湪椤甸潰鍒濆�鍖栫殑鏃跺€欒皟鐢ㄤ竴娆★紝杩欓噷鍙�坊鍔犳敮浠樻柟寮忥紝涓嶈�缃�綅缃�級
 	void InitJiesuanZhifu();
 	void InitJiesuanZhifu();
 
 
-	//这个只更新结算页面支付方式的位置,不处理控件添加
+	//杩欎釜鍙�洿鏂扮粨绠楅〉闈㈡敮浠樻柟寮忕殑浣嶇疆锛屼笉澶勭悊鎺т欢娣诲姞
 	void UpdateJiesuanZhifuPos();
 	void UpdateJiesuanZhifuPos();
 
 
-	//展示结算页面,隐藏选购页面
+	//灞曠ず缁撶畻椤甸潰锛岄殣钘忛€夎喘椤甸潰
 	void ShowJiesuanPage();
 	void ShowJiesuanPage();
 
 
-	//展示选购页面,隐藏结算页面
+	//展示选购页面,隐藏结算页面
 	void ShowXuangouPage();
 	void ShowXuangouPage();
 
 
-	//只是刷新取单数量
+	//鍙�槸鍒锋柊鍙栧崟鏁伴噺
 	void RefreshGuadanNum();
 	void RefreshGuadanNum();
 
 
-	//处理按钮点击类事件
+	//处理按钮点击类事件
 	void HandleClickMsg(TNotifyUI& msg);
 	void HandleClickMsg(TNotifyUI& msg);
 
 
-	//处理option切换事件
+	//澶勭悊option鍒囨崲浜嬩欢
 	void HandleSelectChangeMsg(TNotifyUI& msg);
 	void HandleSelectChangeMsg(TNotifyUI& msg);
 
 
-	//处理下拉框、radio的切换事件
+	//处理下拉框、radio的切换事件
 	void HandleItemSelectMsg(TNotifyUI& msg);
 	void HandleItemSelectMsg(TNotifyUI& msg);
 
 
-	//处理编辑框输入内容改变事件
+	//处理编辑框输入内容改变事件
 	void HandleTextChangedMsg(TNotifyUI& msg);
 	void HandleTextChangedMsg(TNotifyUI& msg);
 
 
-	//处理扫码枪捕捉到的扫码信息
+	//处理扫码枪捕捉到的扫码信息
 	void HandleTextCapture(std::string content);
 	void HandleTextCapture(std::string content);
 
 
-	//处理自定义消息,各个页面处理各个页面自己的(是自己处理的消息返回true,不是自己处理的消息返回false)
+	//处理自定义消息,各个页面处理各个页面自己的(是自己处理的消息返回true,不是自己处理的消息返回false)
 	bool HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
 	bool HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
 
 
 	void UpdateShopcartShow();
 	void UpdateShopcartShow();
 
 
-	//任何可以引起价格变化的,比如添加、修改、删除商品,或者修改优惠等,需要重新计算总价格,刷新结算账单等地方的显示,都要调用这个方法
+	//任何可以引起价格变化的,比如添加、修改、删除商品,或者修改优惠等,需要重新计算总价格,刷新结算账单等地方的显示,都要调用这个方法
 	void UpdateJiesuanInfo();
 	void UpdateJiesuanInfo();
 
 
-	//点击某一个商品的item之后的处理逻辑
+	//鐐瑰嚮鏌愪竴涓�晢鍝佺殑item涔嬪悗鐨勫�鐞嗛€昏緫
 	void ClickFoodAction();
 	void ClickFoodAction();
 
 
-	//点击加号之后的逻辑
+	//鐐瑰嚮鍔犲彿涔嬪悗鐨勯€昏緫
 	void ClickAdd();
 	void ClickAdd();
 
 
-	//点击减号之后的逻辑
+	//鐐瑰嚮鍑忓彿涔嬪悗鐨勯€昏緫
 	void ClickDel();
 	void ClickDel();
 
 
-	//点击删除之后的逻辑
+	//鐐瑰嚮鍒犻櫎涔嬪悗鐨勯€昏緫
 	void ClickRemove();
 	void ClickRemove();
 
 
-	//点击规格之后的逻辑
+	//鐐瑰嚮瑙勬牸涔嬪悗鐨勯€昏緫
 	void ClickGuige();
 	void ClickGuige();
 
 
-	//点击打包之后的逻辑
+	//鐐瑰嚮鎵撳寘涔嬪悗鐨勯€昏緫
 	void ClickDabao();
 	void ClickDabao();
 
 
-	//点击清空之后的逻辑
+	//鐐瑰嚮娓呯┖涔嬪悗鐨勯€昏緫
 	void ClickQingkong();
 	void ClickQingkong();
 
 
-	//点击存单之后的逻辑
+	//鐐瑰嚮瀛樺崟涔嬪悗鐨勯€昏緫
 	void ClickCundan();
 	void ClickCundan();
 
 
-	//点击取单之后的逻辑
+	//鐐瑰嚮鍙栧崟涔嬪悗鐨勯€昏緫
 	void ClickQudan();
 	void ClickQudan();
 
 
-	//点击整单备注之后的逻辑
+	//鐐瑰嚮鏁村崟澶囨敞涔嬪悗鐨勯€昏緫
 	void ClickZhengdanMemo();
 	void ClickZhengdanMemo();
 
 
-	//点击更多支付之后的逻辑
+	//鐐瑰嚮鏇村�鏀�粯涔嬪悗鐨勯€昏緫
 	void ClickGengduoPay();
 	void ClickGengduoPay();
 
 
-	//点击查看优惠
+	//鐐瑰嚮鏌ョ湅浼樻儬
 	void ClickChakanYouhui();
 	void ClickChakanYouhui();
 
 
-	//处理会员登录
+	//澶勭悊浼氬憳鐧诲綍
 	void ClickMemberLogin();
 	void ClickMemberLogin();
 
 
-	//处理会员退出登陆
+	//处理会员退出登陆
 	void ClickMemberLogout();
 	void ClickMemberLogout();
 
 
-	//展示会员详情
+	//灞曠ず浼氬憳璇︽儏
 	void ClickMemberInfoShow();
 	void ClickMemberInfoShow();
 
 
-	//点击整单折扣
+	//鐐瑰嚮鏁村崟鎶樻墸
 	void ClickZhekou();
 	void ClickZhekou();
 
 
-	//点击加价
+	//鐐瑰嚮鍔犱环
 	void ClickJiajia();
 	void ClickJiajia();
 
 
-	//点击优惠
+	//鐐瑰嚮浼樻儬
 	void ClickRengongyouhui();
 	void ClickRengongyouhui();
 
 
-	//点击扫码使用优惠券
+	//点击扫码使用优惠券
 	void ClickSaomaYouhuiquan();
 	void ClickSaomaYouhuiquan();
 
 
-	//点击扫码商品券
+	//点击扫码商品券
 	void ClickSaomaShangpinquan();
 	void ClickSaomaShangpinquan();
 
 
-	//点击扫码权益卡
+	//点击扫码权益卡
 	void ClickSaomaQuanyika();
 	void ClickSaomaQuanyika();
 
 
-	//点击扫码次卡
+	//鐐瑰嚮鎵�爜娆″崱
 	void ClickSaomaCika();
 	void ClickSaomaCika();
 
 
-	//点击取消使用优惠券
+	//点击取消使用优惠券
 	void ClickQuxiaoYouhuiquan();
 	void ClickQuxiaoYouhuiquan();
 
 
-	//点击取消商品券
+	//点击取消商品券
 	void ClickQuxiaoShangpinquan();
 	void ClickQuxiaoShangpinquan();
 
 
-	//点击取消权益卡
+	//点击取消权益卡
 	void ClickQuxiaoQuanyika();
 	void ClickQuxiaoQuanyika();
 
 
-	//点击取消次卡
+	//鐐瑰嚮鍙栨秷娆″崱
 	void ClickQuxiaoCika();
 	void ClickQuxiaoCika();
 
 
-	//点击餐牌号按钮
+	//点击餐牌号按钮
 	void ClickCanpai();
 	void ClickCanpai();
 
 
-	//开始进行微信支付收款,如果fukuanma不为空,默认自动唤起支付
+	//寮€濮嬭繘琛屽井淇℃敮浠樻敹娆撅紝濡傛灉fukuanma涓嶄负绌猴紝榛樿�鑷�姩鍞よ捣鏀�粯
 	void StartWeixinzhifuShoukuan(std::string fukuanma = "");
 	void StartWeixinzhifuShoukuan(std::string fukuanma = "");
 
 
-	//开始进行会员收款
+	//开始进行会员收款
 	void StartHuiyuanShoukuan();
 	void StartHuiyuanShoukuan();
 
 
-	//开始进行现金收款
+	//开始进行现金收款
 	void StartXianjinShoukuan();
 	void StartXianjinShoukuan();
 
 
-	//开始进行福利卡收款
+	//寮€濮嬭繘琛岀�鍒╁崱鏀舵�
 	void StartFulikaShoukuan();
 	void StartFulikaShoukuan();
 
 
-	//开始自定义支付收款
+	//寮€濮嬭嚜瀹氫箟鏀�粯鏀舵�
 	void StartZidingyiShoukuan(std::wstring name, std::wstring selfpay_id);
 	void StartZidingyiShoukuan(std::wstring name, std::wstring selfpay_id);
 
 
-	//支付成功后,更新商品库存
+	//鏀�粯鎴愬姛鍚庯紝鏇存柊鍟嗗搧搴撳瓨
 	void UpdateFoodStock(std::string food_stock);
 	void UpdateFoodStock(std::string food_stock);
 
 
-	//扫描了商品条码的逻辑处理,如果找到了这个条码的商品就返回true,如果没找到就返回false
+	//鎵�弿浜嗗晢鍝佹潯鐮佺殑閫昏緫澶勭悊锛屽�鏋滄壘鍒颁簡杩欎釜鏉$爜鐨勫晢鍝佸氨杩斿洖true锛屽�鏋滄病鎵惧埌灏辫繑鍥瀎alse
 	bool SaomiaoBarcode(std::string barcode);
 	bool SaomiaoBarcode(std::string barcode);
 
 
-	//判断是不是标签秤的条码,并进行处理,返回true表示是标签秤的条码,返回false表示不是
+	//鍒ゆ柇鏄�笉鏄�爣绛剧Г鐨勬潯鐮侊紝骞惰繘琛屽�鐞嗭紝杩斿洖true琛ㄧず鏄�爣绛剧Г鐨勬潯鐮侊紝杩斿洖false琛ㄧず涓嶆槸
 	bool BiaoqianchengSaomaBarcode(std::string barcode);
 	bool BiaoqianchengSaomaBarcode(std::string barcode);
 
 
-	//开始搜索某个商品名字
+	//开始搜索某个商品名字
 	void StartSearchFood(std::string foodname);
 	void StartSearchFood(std::string foodname);
 
 
-	//停止搜索商品
+	//鍋滄�鎼滅储鍟嗗搧
 	void StopSerachFood();
 	void StopSerachFood();
 
 
-	//执行付款成功后的所有操作逻辑
+	//鎵ц�浠樻�鎴愬姛鍚庣殑鎵€鏈夋搷浣滈€昏緫
 	void StartWorkAfterShoukuan(std::string kucunstring, std::string take_food_code, std::string show_trade_no, std::string shoukuan_type, std::string balance = "", std::string member_number = "");
 	void StartWorkAfterShoukuan(std::string kucunstring, std::string take_food_code, std::string show_trade_no, std::string shoukuan_type, std::string balance = "", std::string member_number = "");
 
 
 	void SetPos(RECT rc, bool bNeedInvalidate = true);
 	void SetPos(RECT rc, bool bNeedInvalidate = true);
 
 
-	//隐藏优惠区域
+	//闅愯棌浼樻儬鍖哄煙
 	void YincangYouhui();
 	void YincangYouhui();
 
 
-	//显示优惠区域
+	//鏄剧ず浼樻儬鍖哄煙
 	void XianshiYouhui();
 	void XianshiYouhui();
 
 
 private:
 private:
-	//获取用于提交订单的参数结构
+	//获取用于提交订单的参数结构
 	std::map<std::string, std::string> GetSendorderParams();
 	std::map<std::string, std::string> GetSendorderParams();
 
 
-	//用于支付完成后,获取用于打印的order
+	//鐢ㄤ簬鏀�粯瀹屾垚鍚庯紝鑾峰彇鐢ㄤ簬鎵撳嵃鐨刼rder
 	CDiandanOrder GetPrintOrderinfo(std::string take_food_code, std::string show_trade_no, std::string shoukuan_type, std::string balance, std::string member_number);
 	CDiandanOrder GetPrintOrderinfo(std::string take_food_code, std::string show_trade_no, std::string shoukuan_type, std::string balance, std::string member_number);
 
 
+	void HandleDiandanAIShibie();
+
+	void HandleDiandanAIShibieResult();
+
 private:
 private:
 	CTileLayoutUI* m_foodLayout;
 	CTileLayoutUI* m_foodLayout;
 	CHorizontalLayoutUI* m_foodtypeLayout;
 	CHorizontalLayoutUI* m_foodtypeLayout;
 
 
 	bool m_is_zidingyizhifu_init = false;
 	bool m_is_zidingyizhifu_init = false;
-
 	bool m_is_ai_shibie = false;
 	bool m_is_ai_shibie = false;
-
 	YoloFeatureManager m_yoloFeatureManager;
 	YoloFeatureManager m_yoloFeatureManager;
+	std::string m_ai_shibie_foodname;
 
 
-	//套餐商品数量
+	//濂楅�鍟嗗搧鏁伴噺
 	int m_nFoodpackageNum;
 	int m_nFoodpackageNum;
 
 
-	//所有商品分类(只包含收银机显示的分类)
+	//鎵€鏈夊晢鍝佸垎绫伙紙鍙�寘鍚�敹閾舵満鏄剧ず鐨勫垎绫伙級
 	std::vector<CFoodType> m_types;
 	std::vector<CFoodType> m_types;
 
 
-	//当前选中的商品分类ID,为空表示没选中任何分类,为taocan表示选中套餐分类,如果选中普通商品分类就是分类ID
+	//褰撳墠閫変腑鐨勫晢鍝佸垎绫籌D锛屼负绌鸿〃绀烘病閫変腑浠讳綍鍒嗙被锛屼负taocan琛ㄧず閫変腑濂楅�鍒嗙被锛屽�鏋滈€変腑鏅�€氬晢鍝佸垎绫诲氨鏄�垎绫籌D
 	std::string m_cur_type_id = "";
 	std::string m_cur_type_id = "";
 	CControlUI* m_curFoodtypeOption;
 	CControlUI* m_curFoodtypeOption;
 
 
-	//商品搜索相关
+	//鍟嗗搧鎼滅储鐩稿叧
 	std::string m_type_id_before_sousuo;
 	std::string m_type_id_before_sousuo;
 	std::string m_sousuo_foodname;
 	std::string m_sousuo_foodname;
 
 
-	//当前点击的哪个商品
+	//当前点击的哪个商品
 	CDiandanFoodItemUI* m_cur_click_food_item;
 	CDiandanFoodItemUI* m_cur_click_food_item;
 	
 	
-	//当前购物车的订单,根据这个来进行渲染显示
+	//褰撳墠璐�墿杞︾殑璁㈠崟锛屾牴鎹�繖涓�潵杩涜�娓叉煋鏄剧ず
 	CDiandanOrder m_cur_diandan_order;
 	CDiandanOrder m_cur_diandan_order;
 
 
-	//当前挂单的订单
+	//当前挂单的订单
 	std::vector<CDiandanOrder> m_guadan_orders;
 	std::vector<CDiandanOrder> m_guadan_orders;
 
 
-	//下面是结算相关信息
+	//下面是结算相关信息
 
 
-	//总的优惠
+	//鎬荤殑浼樻儬
 	double m_total_youhui;
 	double m_total_youhui;
 
 
-	//折扣
+	//鎶樻墸
 	int m_zhekou_value;
 	int m_zhekou_value;
 	double m_zhekou_youhui;
 	double m_zhekou_youhui;
 
 
-	//人工加价
+	//浜哄伐鍔犱环
 	double m_jiajia;
 	double m_jiajia;
 
 
-	//人工优惠
+	//浜哄伐浼樻儬
 	double m_rengong_youhui;
 	double m_rengong_youhui;
 
 
-	//开台费
+	//寮€鍙拌垂
 	double m_kaitai;
 	double m_kaitai;
 
 
-	//茶位费
+	//茶位费
 	double m_chawei;
 	double m_chawei;
 
 
-	//打包费
+	//打包费
 	double m_dabao;
 	double m_dabao;
 
 
-	//优惠券
+	//优惠券
 	bool m_is_youhuiquan;
 	bool m_is_youhuiquan;
 	std::string m_youhuiquan_id;
 	std::string m_youhuiquan_id;
 	std::string m_coupon_basic_price;
 	std::string m_coupon_basic_price;
@@ -269,46 +272,46 @@ private:
 	std::string m_coupon_value;
 	std::string m_coupon_value;
 	double m_youhuiquan_youhui;
 	double m_youhuiquan_youhui;
 
 
-	//商品券
-	bool m_is_shangpinquan; //是否核销的商品券
+	//商品券
+	bool m_is_shangpinquan; //鏄�惁鏍搁攢鐨勫晢鍝佸埜
 	std::string m_shangpinquan_lewaimai_customer_id;
 	std::string m_shangpinquan_lewaimai_customer_id;
 	std::string m_shangpinquan_id;
 	std::string m_shangpinquan_id;
 	std::string m_shangpinquan_name;
 	std::string m_shangpinquan_name;
 	std::string m_shangpinquan_foodid;
 	std::string m_shangpinquan_foodid;
-	double m_shangpinquan_youhui; //商品券优惠金额
+	double m_shangpinquan_youhui; //商品券优惠金额
 
 
-	//次卡
+	//娆″崱
 	bool m_is_cika;
 	bool m_is_cika;
 	std::string m_cika_lewaimai_customer_id;
 	std::string m_cika_lewaimai_customer_id;
 	std::string m_cika_id;
 	std::string m_cika_id;
-	std::string m_cika_deduct_type; //次卡优惠类型,0=>折扣,1=>满减,2=>抵扣,3=>指定商品兑换
-	std::string m_cika_discount; //折扣信息
-	std::string m_cika_discount_value; //折扣打折值
-	std::string m_cika_full_reduce; //满减信息
-	std::string m_cika_full_reduce_value; //满减,例如 200,100中间逗号隔开
+	std::string m_cika_deduct_type; //次卡优惠类型,0=>折扣,1=>满减,2=>抵扣,3=>指定商品兑换
+	std::string m_cika_discount; //鎶樻墸淇℃伅
+	std::string m_cika_discount_value; //折扣打折值
+	std::string m_cika_full_reduce; //婊″噺淇℃伅
+	std::string m_cika_full_reduce_value; //满减,例如 200,100中间逗号隔开
 	std::string m_cika_offer;
 	std::string m_cika_offer;
 	std::string m_cika_offer_value;
 	std::string m_cika_offer_value;
 	std::string m_cika_bind_foods_id;
 	std::string m_cika_bind_foods_id;
 	double m_cika_youhui;
 	double m_cika_youhui;
 
 
-	//权益卡
+	//权益卡
 	bool m_is_quanyika;
 	bool m_is_quanyika;
-	std::string m_quanyika_discount; //这里是接口返回的,实际上店铺设置里面也有一个
+	std::string m_quanyika_discount; //这里是接口返回的,实际上店铺设置里面也有一个
 	double m_quanyika_youhui;
 	double m_quanyika_youhui;
 
 
-	//抹零 0:不抹零 1:抹零到角 2:抹零到元
+	//抹零 0:不抹零 1:抹零到角 2:抹零到元
 	int m_moling_type;
 	int m_moling_type;
 	double m_moling_youhui;
 	double m_moling_youhui;
 
 
-	//会员相关
+	//浼氬憳鐩稿叧
 	bool m_is_member = false;
 	bool m_is_member = false;
 	std::string m_member_name;
 	std::string m_member_name;
 	std::string m_member_level;
 	std::string m_member_level;
 	std::string m_member_level_name;
 	std::string m_member_level_name;
 
 
-	double m_total_member_youhui; //会员商品优惠
+	double m_total_member_youhui; //浼氬憳鍟嗗搧浼樻儬
 
 
-	//会员登录成功后返回的会员信息
+	//浼氬憳鐧诲綍鎴愬姛鍚庤繑鍥炵殑浼氬憳淇℃伅
 	std::string m_card_no;
 	std::string m_card_no;
 	std::string m_balance;
 	std::string m_balance;
 	std::string m_phone;
 	std::string m_phone;
@@ -325,30 +328,30 @@ private:
 	std::string m_member_id;
 	std::string m_member_id;
 
 
 	bool m_is_member_zhekou = false;
 	bool m_is_member_zhekou = false;
-	std::string m_member_zhekou_value; //具体会员打几折
-	double m_member_zhekou_youhui; //会员店铺折扣优惠
+	std::string m_member_zhekou_value; //具体会员打几折
+	double m_member_zhekou_youhui; //浼氬憳搴楅摵鎶樻墸浼樻儬
 
 
-	//满减
+	//婊″噺
 	double m_manjian_youhui;
 	double m_manjian_youhui;
 
 
-	//当前应收总价
+	//褰撳墠搴旀敹鎬讳环
 	double m_cur_total_price;
 	double m_cur_total_price;
 
 
-	//仅用于现金收银成功后,对于实收和找零的临时记录
+	//仅用于现金收银成功后,对于实收和找零的临时记录
 	std::string m_shishou_value;
 	std::string m_shishou_value;
 	std::string m_zhaoling_value;
 	std::string m_zhaoling_value;
 
 
-	//餐牌
+	//椁愮墝
 	std::string m_canpai;
 	std::string m_canpai;
 
 
-	//模态对话框有关的
+	//模态对话框有关的
 	bool m_is_show_modal_wnd = false;
 	bool m_is_show_modal_wnd = false;
 	CModalWnd* m_curModalWnd;
 	CModalWnd* m_curModalWnd;
 
 
-	//结算页面总的支付方式数量
+	//缁撶畻椤甸潰鎬荤殑鏀�粯鏂瑰紡鏁伴噺
 	int m_nZhiufuNum;
 	int m_nZhiufuNum;
 
 
-	//当前控件的实际宽度
+	//当前控件的实际宽度
 	int m_nPageWidth;
 	int m_nPageWidth;
 
 
 	bool m_is_yincangyouhui = false;
 	bool m_is_yincangyouhui = false;

BIN
zhipuzi_pos_windows/resource/skin.zip


+ 16 - 16
zhipuzi_pos_windows/tool/CAppEnv.cpp

@@ -1,4 +1,4 @@
-#include "../pch/pch.h"
+#include "../pch/pch.h"
 #include "CAppEnv.h"
 #include "CAppEnv.h"
 
 
 #include "../print/CPosPrinterQueue.h"
 #include "../print/CPosPrinterQueue.h"
@@ -6,7 +6,7 @@
 #include "../worker/CMqttClientWorker.h"
 #include "../worker/CMqttClientWorker.h"
 #include "../worker/CCommonWorker.h"
 #include "../worker/CCommonWorker.h"
 #include "../worker/CVoiceWorker.h"
 #include "../worker/CVoiceWorker.h"
-#include "../worker/CVideoCapture.h"
+#include "../worker/CVideoCaptureWorker.h"
 #include "CShuangpingTool.h"
 #include "CShuangpingTool.h"
 
 
 CAppEnv::CAppEnv()
 CAppEnv::CAppEnv()
@@ -20,42 +20,42 @@ CAppEnv::~CAppEnv()
 
 
 void CAppEnv::Start()
 void CAppEnv::Start()
 {
 {
-	//初始化配置
+	//初始化配置
 	CSetting::GetInstance()->Init();
 	CSetting::GetInstance()->Init();
 
 
-	//启动打印队列
+	//鍚�姩鎵撳嵃闃熷垪
 	CPosPrinterQueue::GetInstance()->StartWork();
 	CPosPrinterQueue::GetInstance()->StartWork();
 
 
-	//启动称重任务
+	//鍚�姩绉伴噸浠诲姟
 	CChengzhongWorker::GetInstance()->StartWork();
 	CChengzhongWorker::GetInstance()->StartWork();
 
 
-	//启动声音任务
+	//鍚�姩澹伴煶浠诲姟
 	CVoiceWorker::GetInstance()->Start();
 	CVoiceWorker::GetInstance()->Start();
 
 
-	//启动通用任务
+	//鍚�姩閫氱敤浠诲姟
 	CCommonWorker::GetInstance()->Start();
 	CCommonWorker::GetInstance()->Start();
 
 
-	//启动摄像头任务
-	CVideoCapture::GetInstance()->Start();
+	//启动摄像头任务
+	CVideoCaptureWorker::GetInstance()->Start();
 
 
-	//初始化副屏
+	//初始化副屏
 	CShuangpingTool::GetInstance()->Init();
 	CShuangpingTool::GetInstance()->Init();
 }
 }
 
 
 void CAppEnv::Stop()
 void CAppEnv::Stop()
 {
 {
-	//停止打印任务
+	//鍋滄�鎵撳嵃浠诲姟
 	CPosPrinterQueue::GetInstance()->StopWork();
 	CPosPrinterQueue::GetInstance()->StopWork();
 
 
-	//停止称重任务
+	//鍋滄�绉伴噸浠诲姟
 	CChengzhongWorker::GetInstance()->StopWork();
 	CChengzhongWorker::GetInstance()->StopWork();
 
 
-	//停止声音任务
+	//鍋滄�澹伴煶浠诲姟
 	CVoiceWorker::GetInstance()->Stop();
 	CVoiceWorker::GetInstance()->Stop();
 
 
-	//停止摄像头任务
-	CVideoCapture::GetInstance()->Stop();
+	//停止摄像头任务
+	CVideoCaptureWorker::GetInstance()->Stop();
 
 
-	//停止通用任务
+	//鍋滄�閫氱敤浠诲姟
 	CCommonWorker::GetInstance()->Stop();
 	CCommonWorker::GetInstance()->Stop();
 }
 }

+ 0 - 78
zhipuzi_pos_windows/worker/CVideoCapture.cpp

@@ -1,78 +0,0 @@
-#include "../pch/pch.h"
-#include "CVideoCapture.h"
-
-//开始工作
-void CVideoCapture::Start()
-{
-	m_is_work = true;
-
-
-	//持续获取摄像头数据,直到程序退出,这里开启一个线程来处理摄像头数据的获取,避免阻塞主线程
-	std::thread(&CVideoCapture::HandleVideoCapture, this).detach();
-}
-
-//停止工作
-void CVideoCapture::Stop()
-{
-    m_is_work = false;
-}
-
-// 新增:自动检测可用摄像头索引
-int CVideoCapture::findAvailableCamera()
-{
-    for (int i = 0; i < 10; i++)
-    { // 检测前10个索引
-        cv::VideoCapture tempCap(i, cv::CAP_DSHOW);
-        if (tempCap.isOpened())
-        {
-            tempCap.release();
-
-            return i;
-        }
-    }
-    return -1;
-}
-
-void CVideoCapture::HandleVideoCapture()
-{
-    int cameraIndex = findAvailableCamera();
-    if (cameraIndex == -1)
-    {
-        DEBUG_LOG("未找到任何可用摄像头!");
-        return;
-    }
-    cv::VideoCapture cap(cameraIndex, cv::CAP_DSHOW);
-
-    if (!cap.isOpened())
-    {
-        CSystem::my_sleep(1);
-        DEBUG_LOG("打开摄像头失败,正在重试...");
-        
-        return;
-    }
-
-    DEBUG_LOG("摄像头打开成功!");
-
-    while (m_is_work == true)
-    {
-        // 读取摄像头帧
-        cap >> m_frame;
-        if (m_frame.empty())
-        {
-            DEBUG_LOG("读取摄像头帧失败,正在重试...");
-            CSystem::my_sleep(1);
-            continue;
-        }
-
-		//什么都不用做,只需要把摄像头读取的帧放在成员变量里就行,后续其他地方需要用到摄像头数据的时候直接从成员变量里取就行了
-        // 显示摄像头帧(可选)
-        // cv::imshow("Camera", m_frame);
-		// if (cv::waitKey(30) >= 0) break; // 按任意键退出
-    }
-
-    // ====================== 资源释放 ======================
-    cap.release();
-    cv::destroyAllWindows();
-
-    return;
-}

+ 84 - 0
zhipuzi_pos_windows/worker/CVideoCaptureWorker.cpp

@@ -0,0 +1,84 @@
+#include "../pch/pch.h"
+#include "CVideoCaptureWorker.h"
+
+//开始工作
+void CVideoCaptureWorker::Start()
+{
+	m_is_work = true;
+
+
+	//持续获取摄像头数据,直到程序退出,这里开启一个线程来处理摄像头数据的获取,避免阻塞主线程
+	std::thread(&CVideoCaptureWorker::HandleVideoCapture, this).detach();
+}
+
+//停止工作
+void CVideoCaptureWorker::Stop()
+{
+    m_is_work = false;
+}
+
+// 新增:自动检测可用摄像头索引
+int CVideoCaptureWorker::findAvailableCamera()
+{
+    for (int i = 0; i < 10; i++)
+    { // 检测前10个索引
+        cv::VideoCapture tempCap(i, cv::CAP_DSHOW);
+        if (tempCap.isOpened())
+        {
+            tempCap.release();
+
+            return i;
+        }
+    }
+    return -1;
+}
+
+void CVideoCaptureWorker::HandleVideoCapture()
+{
+    int cameraIndex = findAvailableCamera();
+    if (cameraIndex == -1)
+    {
+        DEBUG_LOG("未找到任何可用摄像头!");
+        return;
+    }
+    cv::VideoCapture cap(cameraIndex, cv::CAP_DSHOW);
+
+    if (!cap.isOpened())
+    {
+        CSystem::my_sleep(1);
+        DEBUG_LOG("打开摄像头失败,正在重试...");
+        
+        return;
+    }
+
+    DEBUG_LOG("摄像头打开成功!");
+
+    while (m_is_work == true)
+    {
+		//m_worker_mutex.lock();
+
+        // 读取摄像头帧
+        cap >> m_frame;
+        if (m_frame.empty())
+        {
+			//m_worker_mutex.unlock();
+
+            DEBUG_LOG("读取摄像头帧失败,正在重试...");
+            CSystem::my_sleep(1);
+            continue;
+        }
+
+        //m_worker_mutex.unlock();
+
+		//什么都不用做,只需要把摄像头读取的帧放在成员变量里就行,后续其他地方需要用到摄像头数据的时候直接从成员变量里取就行了
+        // 显示摄像头帧(可选)
+        // cv::imshow("Camera", m_frame);
+		// if (cv::waitKey(30) >= 0) break; // 按任意键退出
+    }
+
+    // ====================== 资源释放 ======================
+    cap.release();
+    cv::destroyAllWindows();
+
+    return;
+}

+ 9 - 7
zhipuzi_pos_windows/worker/CVideoCapture.h

@@ -1,22 +1,23 @@
-#pragma once
+#pragma once
 
 
 #include <opencv2/opencv.hpp>
 #include <opencv2/opencv.hpp>
 #include <opencv2/dnn.hpp>
 #include <opencv2/dnn.hpp>
 
 
-class CVideoCapture
+//这个Worker�负责从摄�头读�图�数�,�负责进行任何处�
+class CVideoCaptureWorker
 {
 {
 public:
 public:
-	static CVideoCapture * GetInstance()
+	static CVideoCaptureWorker * GetInstance()
 	{
 	{
-		static CVideoCapture instance;
+		static CVideoCaptureWorker instance;
 
 
 		return &instance;
 		return &instance;
 	}
 	}
 
 
-	//¿ªÊ¼¹¤×÷
+	//开始工作
 	void Start();
 	void Start();
 	
 	
-	//Í£Ö¹¹¤×÷
+	//�止工作
 	void Stop();
 	void Stop();
 
 
 	void HandleVideoCapture();
 	void HandleVideoCapture();
@@ -32,5 +33,6 @@ private:
 	bool m_is_work;
 	bool m_is_work;
 
 
 	cv::Mat m_frame;
 	cv::Mat m_frame;
-};
 
 
+	std::mutex m_worker_mutex;
+};

+ 2 - 2
zhipuzi_pos_windows/zhipuzi_pos_windows.cpp

@@ -29,12 +29,12 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
 	CLewaimaiLog log;
 	CLewaimaiLog log;
 	log.Init();
 	log.Init();
 
 
-	//AITest();
-
 	//初始化所有配置,启动所有异步worker
 	//初始化所有配置,启动所有异步worker
 	CAppEnv app;
 	CAppEnv app;
 	app.Start();
 	app.Start();
 
 
+	//AITest();
+
     //开始展示窗口
     //开始展示窗口
     CPaintManagerUI::SetInstance(hInstance);
     CPaintManagerUI::SetInstance(hInstance);
 
 

+ 3 - 2
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj

@@ -240,8 +240,9 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="ai\ImageProcessor.h" />
     <ClInclude Include="ai\ImageProcessor.h" />
     <ClInclude Include="ai\SQLiteVecManager.h" />
     <ClInclude Include="ai\SQLiteVecManager.h" />
+    <ClInclude Include="ai\YoloClassName.h" />
     <ClInclude Include="ai\YoloFeatureManager.h" />
     <ClInclude Include="ai\YoloFeatureManager.h" />
-    <ClInclude Include="worker\CVideoCapture.h" />
+    <ClInclude Include="worker\CVideoCaptureWorker.h" />
     <ClInclude Include="sqlite3\sqlite-vec.h" />
     <ClInclude Include="sqlite3\sqlite-vec.h" />
     <ClInclude Include="sqlite3\sqlite3.h" />
     <ClInclude Include="sqlite3\sqlite3.h" />
     <ClInclude Include="sqlite3\sqlite3ext.h" />
     <ClInclude Include="sqlite3\sqlite3ext.h" />
@@ -370,7 +371,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     <ClCompile Include="ai\test.cpp" />
     <ClCompile Include="ai\test.cpp" />
     <ClCompile Include="ai\test.h" />
     <ClCompile Include="ai\test.h" />
     <ClCompile Include="ai\YoloFeatureManager.cpp" />
     <ClCompile Include="ai\YoloFeatureManager.cpp" />
-    <ClCompile Include="worker\CVideoCapture.cpp" />
+    <ClCompile Include="worker\CVideoCaptureWorker.cpp" />
     <ClCompile Include="sqlite3\shell.c" />
     <ClCompile Include="sqlite3\shell.c" />
     <ClCompile Include="sqlite3\sqlite-vec.c" />
     <ClCompile Include="sqlite3\sqlite-vec.c" />
     <ClCompile Include="sqlite3\sqlite3.c" />
     <ClCompile Include="sqlite3\sqlite3.c" />

+ 5 - 2
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj.filters

@@ -387,7 +387,10 @@
     <ClInclude Include="ai\YoloFeatureManager.h">
     <ClInclude Include="ai\YoloFeatureManager.h">
       <Filter>头文件</Filter>
       <Filter>头文件</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="worker\CVideoCapture.h">
+    <ClInclude Include="worker\CVideoCaptureWorker.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="ai\YoloClassName.h">
       <Filter>头文件</Filter>
       <Filter>头文件</Filter>
     </ClInclude>
     </ClInclude>
   </ItemGroup>
   </ItemGroup>
@@ -740,7 +743,7 @@
     <ClCompile Include="ai\YoloFeatureManager.cpp">
     <ClCompile Include="ai\YoloFeatureManager.cpp">
       <Filter>源文件</Filter>
       <Filter>源文件</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="worker\CVideoCapture.cpp">
+    <ClCompile Include="worker\CVideoCaptureWorker.cpp">
       <Filter>源文件</Filter>
       <Filter>源文件</Filter>
     </ClCompile>
     </ClCompile>
   </ItemGroup>
   </ItemGroup>