test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. // test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #include <iostream>
  4. #include <windows.h>
  5. #include <io.h>
  6. #include <ShellAPI.h>
  7. #include <atltypes.h>
  8. #include <direct.h>
  9. #include "tlhelp32.h"
  10. #include "YoloFeatureExtractor.h"
  11. #include "ImageProcessor.h"
  12. #include "SQLiteVecManager.h"
  13. #include <filesystem>
  14. #include <opencv2/core.hpp>
  15. #include <opencv2/core/ocl.hpp>
  16. #include <opencv2/highgui.hpp>
  17. #include <opencv2/imgcodecs.hpp>
  18. #include <opencv2/imgproc.hpp>
  19. #include <opencv2/opencv.hpp>
  20. #include <iostream>
  21. using namespace cv;
  22. using namespace std;
  23. #include <iostream>
  24. void checkBuild()
  25. {
  26. //查询opencv编译时配置
  27. std::cout << cv::getBuildInformation() << std::endl;
  28. }
  29. void checkSimd()
  30. {
  31. //查询opencv线程
  32. int numTh = cv::getNumThreads(); //默认值是cpu的逻辑线程数
  33. int numCore = cv::getNumberOfCPUs();
  34. std::cout << "getNumThreads=" << numTh << std::endl;
  35. std::cout << "getNumberOfCPUs=" << numCore << std::endl;
  36. //查询opencv当前是否开启了并行优化功能
  37. bool opt = cv::useOptimized(); //默认值是true
  38. std::cout << "useOptimized=" << opt << std::endl;
  39. //查询opencv当前是否支持具体的CPU指令集
  40. bool check1 = cv::checkHardwareSupport(CV_CPU_SSE4_1);
  41. bool check2 = cv::checkHardwareSupport(CV_CPU_SSE4_2);
  42. bool check3 = cv::checkHardwareSupport(CV_CPU_AVX2);
  43. std::cout << "CV_CPU_SSE4_1=" << check1 << std::endl;
  44. std::cout << "CV_CPU_SSE4_2=" << check2 << std::endl;
  45. std::cout << "CV_CPU_AVX2=" << check3 << std::endl;
  46. //查询完整的硬件支持清单
  47. std::cout << "HardwareSupport:" << std::endl;
  48. std::cout << "CV_CPU_MMX: " << cv::checkHardwareSupport(CV_CPU_MMX) << std::endl;
  49. std::cout << "CV_CPU_SSE: " << cv::checkHardwareSupport(CV_CPU_SSE) << std::endl;
  50. std::cout << "CV_CPU_SSE2: " << cv::checkHardwareSupport(CV_CPU_SSE2) << std::endl;
  51. std::cout << "CV_CPU_SSE3: " << cv::checkHardwareSupport(CV_CPU_SSE3) << std::endl;
  52. std::cout << "CV_CPU_SSSE3: " << cv::checkHardwareSupport(CV_CPU_SSSE3) << std::endl;
  53. std::cout << "CV_CPU_SSE4_1: " << cv::checkHardwareSupport(CV_CPU_SSE4_1) << std::endl;
  54. std::cout << "CV_CPU_SSE4_2: " << cv::checkHardwareSupport(CV_CPU_SSE4_2) << std::endl;
  55. std::cout << "CV_CPU_POPCNT: " << cv::checkHardwareSupport(CV_CPU_POPCNT) << std::endl;
  56. std::cout << "CV_CPU_FP16: " << cv::checkHardwareSupport(CV_CPU_FP16) << std::endl;
  57. std::cout << "CV_CPU_AVX: " << cv::checkHardwareSupport(CV_CPU_AVX) << std::endl;
  58. std::cout << "CV_CPU_AVX2: " << cv::checkHardwareSupport(CV_CPU_AVX2) << std::endl;
  59. std::cout << "CV_CPU_FMA3: " << cv::checkHardwareSupport(CV_CPU_FMA3) << std::endl;
  60. std::cout << "CV_CPU_AVX_512F: " << cv::checkHardwareSupport(CV_CPU_AVX_512F) << std::endl;
  61. std::cout << "CV_CPU_AVX_512BW: " << cv::checkHardwareSupport(CV_CPU_AVX_512BW) << std::endl;
  62. std::cout << "CV_CPU_AVX_512CD: " << cv::checkHardwareSupport(CV_CPU_AVX_512CD) << std::endl;
  63. std::cout << "CV_CPU_AVX_512DQ: " << cv::checkHardwareSupport(CV_CPU_AVX_512DQ) << std::endl;
  64. std::cout << "CV_CPU_AVX_512ER: " << cv::checkHardwareSupport(CV_CPU_AVX_512ER) << std::endl;
  65. std::cout << "CV_CPU_AVX_512IFMA512: " << cv::checkHardwareSupport(CV_CPU_AVX_512IFMA512) << std::endl;
  66. std::cout << "CV_CPU_AVX_512IFMA: " << cv::checkHardwareSupport(CV_CPU_AVX_512IFMA) << std::endl;
  67. std::cout << "CV_CPU_AVX_512PF: " << cv::checkHardwareSupport(CV_CPU_AVX_512PF) << std::endl;
  68. std::cout << "CV_CPU_AVX_512VBMI: " << cv::checkHardwareSupport(CV_CPU_AVX_512VBMI) << std::endl;
  69. std::cout << "CV_CPU_AVX_512VL: " << cv::checkHardwareSupport(CV_CPU_AVX_512VL) << std::endl;
  70. std::cout << "CV_CPU_NEON: " << cv::checkHardwareSupport(CV_CPU_NEON) << std::endl;
  71. std::cout << "CV_CPU_VSX: " << cv::checkHardwareSupport(CV_CPU_VSX) << std::endl;
  72. std::cout << "CV_CPU_AVX512_SKX: " << cv::checkHardwareSupport(CV_CPU_AVX512_SKX) << std::endl;
  73. std::cout << "CV_HARDWARE_MAX_FEATURE: " << cv::checkHardwareSupport(CV_HARDWARE_MAX_FEATURE) << std::endl;
  74. std::cout << std::endl;
  75. //cv::setUseOptimized(false);
  76. //cv::setNumThreads(1);
  77. }
  78. void checkOpenCL() //Open Computing Language:开放计算语言,可以附加在主机处理器的CPU或GPU上执行
  79. {
  80. std::vector<cv::ocl::PlatformInfo> info;
  81. cv::ocl::getPlatfomsInfo(info);
  82. cv::ocl::PlatformInfo sdk = info.at(0);
  83. int number = sdk.deviceNumber();
  84. if (number < 1)
  85. {
  86. std::cout << "Number of devices:" << number << std::endl;
  87. return;
  88. }
  89. std::cout << "***********SDK************" << std::endl;
  90. std::cout << "Name:" << sdk.name() << std::endl;
  91. std::cout << "Vendor:" << sdk.vendor() << std::endl;
  92. std::cout << "Version:" << sdk.version() << std::endl;
  93. std::cout << "Version:" << sdk.version() << std::endl;
  94. std::cout << "Number of devices:" << number << std::endl;
  95. for (int i = 0; i < number; i++)
  96. {
  97. std::cout << std::endl;
  98. cv::ocl::Device device;
  99. sdk.getDevice(device, i);
  100. std::cout << "***********Device " << i + 1 << "***********" << std::endl;
  101. std::cout << "Vendor Id:" << device.vendorID() << std::endl;
  102. std::cout << "Vendor name:" << device.vendorName() << std::endl;
  103. std::cout << "Name:" << device.name() << std::endl;
  104. std::cout << "Driver version:" << device.vendorID() << std::endl;
  105. if (device.isAMD())
  106. std::cout << "Is AMD device" << std::endl;
  107. if (device.isIntel())
  108. std::cout << "Is Intel device" << std::endl;
  109. if (device.isNVidia())
  110. std::cout << "Is NVidia device" << std::endl;
  111. std::cout << "Global Memory size:" << device.globalMemSize() << std::endl;
  112. std::cout << "Memory cache size:" << device.globalMemCacheSize() << std::endl;
  113. std::cout << "Memory cache type:" << device.globalMemCacheType() << std::endl;
  114. std::cout << "Local Memory size:" << device.localMemSize() << std::endl;
  115. std::cout << "Local Memory type:" << device.localMemType() << std::endl;
  116. std::cout << "Max Clock frequency:" << device.maxClockFrequency() << std::endl;
  117. }
  118. }
  119. std::wstring getExePath()
  120. {
  121. wchar_t exeFullPath[MAX_PATH]; // Full path
  122. std::wstring strPath = L"";
  123. GetModuleFileName(NULL, exeFullPath, MAX_PATH);
  124. strPath = (std::wstring)exeFullPath; // Get full path of the file
  125. return strPath;
  126. }
  127. std::wstring GetProgramDir()
  128. {
  129. wchar_t exeFullPath[MAX_PATH]; // Full path
  130. std::wstring strPath = L"";
  131. GetModuleFileName(NULL, exeFullPath, MAX_PATH);
  132. strPath = (std::wstring)exeFullPath; // Get full path of the file
  133. int pos = strPath.find_last_of('\\', strPath.length());
  134. return strPath.substr(0, pos); // Return the directory without the file name
  135. }
  136. int main()
  137. {
  138. // ========== 关键:开启OpenCV详细日志 ==========
  139. // 设置日志级别为DEBUG(显示所有报错/警告/调试信息)
  140. utils::logging::setLogLevel(utils::logging::LOG_LEVEL_DEBUG);
  141. // ========== 修复3:依次尝试所有Windows后端 ==========
  142. VideoCapture cap;
  143. // 尝试1:DSHOW后端(最稳定)
  144. cap.open(0, CAP_DSHOW);
  145. if (!cap.isOpened())
  146. {
  147. cout << "DSHOW后端失败,尝试MSMF后端..." << endl;
  148. // 尝试2:MSMF后端
  149. cap.open(0, CAP_MSMF);
  150. if (!cap.isOpened())
  151. {
  152. cout << "MSMF后端失败,尝试默认后端..." << endl;
  153. // 尝试3:默认后端(自动选择)
  154. cap.open(0);
  155. if (!cap.isOpened())
  156. {
  157. cerr << "===== 所有后端都失败! =====" << endl;
  158. cerr << "请检查:1. OpenCV DLL是否复制到工程目录;2. 系统相机是否可用;3. 工程配置是否正确" << endl;
  159. return -1;
  160. }
  161. }
  162. }
  163. // ========== 验证摄像头 ==========
  164. cout << "✅ 摄像头打开成功!" << endl;
  165. cout << "分辨率:" << cap.get(CAP_PROP_FRAME_WIDTH) << "x" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
  166. cout << "摄像头打开成功!" << endl;
  167. cap.release();
  168. return 0;
  169. try
  170. {
  171. // 检查 OpenCL 是否可用
  172. checkBuild();
  173. checkSimd();
  174. //checkOpenCL();
  175. // 检查OpenCL是否可用
  176. if (!cv::ocl::haveOpenCL())
  177. {
  178. std::cout << "opencl不可用" << std::endl;
  179. }
  180. else
  181. {
  182. std::cout << "opencl可用" << std::endl;
  183. // 启用OpenCL
  184. //cv::ocl::setUseOpenCL(true);
  185. }
  186. // 设置路径(可根据实际情况修改)
  187. std::wstring wsExePath = getExePath();
  188. std::wstring wsProgramDir = GetProgramDir();
  189. std::filesystem::path mainDir = wsProgramDir;
  190. #ifdef _WIN64
  191. std::string sMainDir = mainDir.parent_path().parent_path().string();
  192. #else
  193. std::string sMainDir = mainDir.parent_path().string();
  194. #endif // WIN32
  195. std::string modelPath = sMainDir + "/best.onnx"; // YOLO2026模型路径
  196. std::string classesPath = sMainDir + "/cls.names"; // 类别文件路径
  197. std::string galleryDir = sMainDir + "/images"; // 图库目录路径
  198. std::string searchImagePath = sMainDir + "/3.jpg"; // 搜索图片路径
  199. std::string databasePath = sMainDir + "/image_features.db"; // SQLite数据库路径
  200. std::filesystem::remove(databasePath);
  201. std::cout << "=== YOLO2026图像检索系统 (SQLite-Vec版本) ===" << std::endl;
  202. std::cout << "模型路径: " << modelPath << std::endl;
  203. std::cout << "图库路径: " << galleryDir << std::endl;
  204. std::cout << "查询图片: " << searchImagePath << std::endl;
  205. std::cout << "数据库路径: " << databasePath << std::endl;
  206. std::cout << "=========================================" << std::endl;
  207. // 初始化特征提取器
  208. std::cout << "正在初始化YOLO2026特征提取器..." << std::endl;
  209. YoloFeatureExtractor extractor(modelPath, classesPath);
  210. extractor.initOpenCL(); // 启用OpenCL加速(如果可用)
  211. // 获取图库中的所有图片
  212. std::cout << "正在扫描图库中的图片..." << std::endl;
  213. std::vector<std::string> galleryImages = ImageProcessor::getImagesInDirectory(galleryDir);
  214. std::cout << "找到 " << galleryImages.size() << " 张图片" << std::endl;
  215. if (galleryImages.empty())
  216. {
  217. std::cerr << "图库中没有找到有效的图片文件!" << std::endl;
  218. return -1;
  219. }
  220. // 初始化SQLite-Vec数据库
  221. std::cout << "正在初始化SQLite-Vec数据库..." << std::endl;
  222. SQLiteVecManager vecManager(databasePath);
  223. auto start_time = std::chrono::high_resolution_clock::now();
  224. // 检查数据库是否已存在数据
  225. bool databaseExists = vecManager.loadDatabase();
  226. std::cout << "数据库加载结果:" << std::boolalpha << databaseExists << std::endl;
  227. std::cout << "数据集数量:" << vecManager.getFeatureCount() << std::endl;
  228. if (databaseExists && vecManager.getFeatureCount() > 0)
  229. {
  230. std::cout << "数据库已存在 " << vecManager.getFeatureCount() << " 条特征记录" << std::endl;
  231. }
  232. else
  233. {
  234. std::cout << "重新构建数据库..." << std::endl;
  235. // 提取图库图片特征并向量
  236. std::cout << "开始提取图库图片特征..." << std::endl;
  237. int featureDimension = 0;
  238. int processedCount = 0;
  239. // 初始化数据库表结构
  240. vecManager.initializeDatabase(45); // 假设特征维度为1000,实际会在第一次处理时确定
  241. for (size_t i = 0; i < galleryImages.size(); ++i)
  242. {
  243. try
  244. {
  245. std::vector<float> features = extractor.extractFeatures(galleryImages[i]);
  246. if (!features.empty())
  247. {
  248. if (featureDimension == 0)
  249. {
  250. featureDimension = static_cast<int>(features.size());
  251. std::cout << "特征维度: " << featureDimension << std::endl;
  252. // 重新初始化数据库以匹配实际维度
  253. vecManager.initializeDatabase(featureDimension);
  254. }
  255. vecManager.addFeatureVector(features, galleryImages[i]);
  256. processedCount++;
  257. std::cout << "[" << (i + 1) << "/" << galleryImages.size() << "] 已处理: "
  258. << galleryImages[i] << std::endl;
  259. }
  260. }
  261. catch (const std::exception & e)
  262. {
  263. std::cerr << "处理失败 [" << (i + 1) << "]: " << galleryImages[i]
  264. << " (" << e.what() << ")" << std::endl;
  265. }
  266. }
  267. auto end_time = std::chrono::high_resolution_clock::now();
  268. auto duration = std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time);
  269. std::cout << "特征提取完成,耗时: " << duration.count() << " 秒" << std::endl;
  270. std::cout << "成功处理图片数量: " << processedCount << std::endl;
  271. std::cout << "数据库记录数量: " << vecManager.getFeatureCount() << std::endl;
  272. if (processedCount == 0)
  273. {
  274. std::cerr << "没有成功提取任何图片特征!" << std::endl;
  275. return -1;
  276. }
  277. // 保存数据库
  278. vecManager.saveDatabase();
  279. std::cout << "数据库保存完成" << std::endl;
  280. }
  281. // 提取查询图片特征
  282. std::cout << "正在提取查询图片特征: " << searchImagePath << std::endl;
  283. std::vector<float> queryFeatures = extractor.extractFeatures(searchImagePath);
  284. if (queryFeatures.empty())
  285. {
  286. std::cerr << "无法提取查询图片特征!" << std::endl;
  287. return -1;
  288. }
  289. std::cout << "查询图片特征提取完成,维度: " << queryFeatures.size() << std::endl;
  290. // 进行相似性搜索
  291. std::cout << "正在进行相似性搜索..." << std::endl;
  292. std::vector<std::pair<std::string, float>> searchResults = vecManager.searchSimilarVectors(queryFeatures, 5);
  293. // 显示搜索结果
  294. std::cout << "\n=== 搜索结果 ===" << std::endl;
  295. std::cout << "查询图片: " << searchImagePath << std::endl;
  296. std::cout << "最相似的图片:" << std::endl;
  297. for (size_t i = 0; i < searchResults.size(); ++i)
  298. {
  299. std::cout << (i + 1) << ". " << searchResults[i].first
  300. << " (相似度: " << searchResults[i].second << ")" << std::endl;
  301. }
  302. std::cout << "\n图像检索完成!" << std::endl;
  303. }
  304. catch (const std::exception & e)
  305. {
  306. std::string a = e.what();
  307. std::cerr << "程序执行出错: " << e.what() << std::endl;
  308. return -1;
  309. }
  310. sqlite3_sleep(100000);
  311. return 0;
  312. }