网站友情链接购买android应用开发基础

当前位置: 首页 > news >正文

网站友情链接购买,android应用开发基础,北京服务设计,网站建设中最重要的环节前言 ​ 文章开始#xff0c;瞎说一点其他的东西#xff0c;真的是很离谱#xff0c;找了至少两三个小时#xff0c;就一个简单的需求#xff1a; 1、利用OpenCV 在Windows进行抓图 2、利用OpenCV 进行连续数字的检测。 3、使用C#xff0c;Qt 3、将检测的结果显示出来 …前言 ​ 文章开始瞎说一点其他的东西真的是很离谱找了至少两三个小时就一个简单的需求 1、利用OpenCV 在Windows进行抓图 2、利用OpenCV 进行连续数字的检测。 3、使用CQt 3、将检测的结果显示出来 ​ 就这么简单的需求结果网上找了各种版本硬是找不到,要是代码可能没啥问题但是运行不了你这运行不了我怎么知道你到底能不能用我代码调半天能用了结果你跟我说最后效果不好为啥呢 ​ 因为图像识别这种东西很取决于你的外部环境的一定你的外部环境变量你的数字的背景啥的变了那么你的代码肯定就要做相应的调整这种不像深度学习能够自己学习的实际只能靠你自己一步一步的去调试验证效果怎么样最终得到适合你的。 ​ 所以我下面会给出我这个程序的打包的可直接验证效果的版本你如果不是一个想调代码的人或是你不是一个有耐心的人或者你跟我的识别环境不一致 那么我估计我的代码你也用不了也不必去下载了。可继续找下一个了。 ​ 但如果你说只要我代码能让你运行起来那么你就能够花精力把它调出来实在不行你让AI 帮你把它调出来这都是没问题的因为目前的运行方式很简单只要你确保环境跟我一致基本就没啥问题。 环境: Windows 10 Qt 12.8 MSVC2015 OpenCV 4.5.5我带的这个opencv 是用VS2015编译出来的如果没有MSVC2015 那么就只能靠你自己去下载一个MinGW 之类的或是你自己对应版本的OpenCV了 运行现象
因为这个是采用那个SVM首先进行模型训练的我的模型每个数字只放了一张或是两张训练量太小了出来的效果就比较不好而且若要进行这个识别肯定要注意以下几点 1、摄像头与数字的距离一定是固定的然后外部光源也是固定的不能说一会亮一会不亮的这是不合理的。 2、需要拍摄更多组的照片以及数字来进行训练甚至该模型可以采用自训练的方式来进行优化但我这个版本就没有做到这个点了这个点有需要的可以来进行优化。后面对这个方面如果我有进行优化我会来跟贴的。 3、可以对捕抓到的数字再进行一些处理增大SVM训练的量这样可能效果就会稳定很多了我上面这个摄像头是手拿着的所以会一直飘我觉得应该也是比较正常的毕竟只用了一天时间搞出了这个demo那效果肯定会有差强人意的地方。 可运行程序 通过网盘分享的文件NumberRecognitionTool.zip 链接: https://pan.baidu.com/s/1hr8VqU2x17pIQ561hy8nQw?pwd1111 提取码: 1111 我有试了一下是可以运行的如果不能运行可以留言下我看下是什么原因。 如下我会把我的核心代码给贴上去如果有环境的直接改一改运行就可以了。如果还觉得有点懒的话可以直接下载我上传的资源文件那里面我会把dll啥的都给你打包好直接运行即可。不过要花费点积分就是了如果又没有积分的话可以加我qq或者私信我我可以直接发你。qq在主页有。 https://download.csdn.net/download/qq_4321106090468759?spm1001.2014.3001.5501 我也下载了好一些往上的资源我也不知道有没有用反正我没用上如果有需要的话也可以一起发给你们。希望能对你们有帮助。 正文 一、代码 处理的核心代码 void CDataRecognitionMgr::InitSVM() {srand((unsigned)time(0)); // 设置随机数种子// 定义数字图像尺寸30x50digitWidth 30;digitHeight 50;hog cv::HOGDescriptor(cv::Size(digitWidth, digitHeight), // winSizecv::Size(10, 10), // blockSizecv::Size(5, 5), // blockStridecv::Size(5, 5), // cellSize9 // nbins);descriptorSize (int)hog.getDescriptorSize();// // 1. 从外部加载模板图像并生成数据增强后的训练样本// vectorMat trainImages;vectorint trainLabels;const int numAugmentations 100; // 每个数字至少生成 100 个训练样本for (int digit 0; digit 10; digit) {// 模板图像存放在指定目录下根据需要调整路径与图片格式string folderPattern ./img/Mod/ to_string(digit) /*.png;vectorString files;glob(folderPattern, files, false);if (files.empty()) {cout 未找到数字 digit 的模板图片请检查文件夹: folderPattern endl;continue;}// 生成数据增强样本for (int i 0; i numAugmentations; i) {// 随机选择一个模板图片int idx rand() % files.size();Mat img imread(files[idx], IMREAD_GRAYSCALE);if (img.empty()) {cout 加载图片失败: files[idx] endl;continue;}// 对模板图像进行增强处理Mat augImg augmentImage(img, digitWidth, digitHeight);trainImages.push_back(augImg);trainLabels.push_back(digit);}}int totalSamples (int)trainImages.size();if (totalSamples 0) {cout 未生成任何训练样本请检查模板图像路径与数据增强处理 endl;return;}cout 生成的训练样本总数: totalSamples endl;// // 2. 构造训练数据矩阵// Mat trainingFeatures(totalSamples, descriptorSize, CV_32F);Mat trainingLabelsMat(totalSamples, 1, CV_32S);for (int i 0; i totalSamples; i) {vectorfloat descriptors;hog.compute(trainImages[i], descriptors);for (int j 0; j descriptorSize; j) {trainingFeatures.atfloat(i, j) descriptors[j];}trainingLabelsMat.atint(i, 0) trainLabels[i];}// // 3. 使用 SVMRBF 核训练分类器// svm SVM::create();svm-setType(SVM::C_SVC);svm-setKernel(SVM::RBF);svm-setC(2.0);svm-setGamma(0.005);svm-setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 1000, 1e-6));cout 开始训练 SVM… endl;svm-train(trainingFeatures, ml::ROW_SAMPLE, trainingLabelsMat);cout SVM 训练完成。 endl; }void CDataRecognitionMgr::HandlerImage(const QImage _oImg) { #if 1Mat mat _ImageToMat(_oImg);Mat matGray;cvtColor(mat, matGray, COLOR_BGR2GRAY);Mat testImgThresh;threshold(matGray, testImgThresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU); // imshow(testImgThresh,testImgThresh);Mat struct1;struct1getStructuringElement(0,Size(2,2));//矩形结构元素Mat erodeSrc;//存放腐蚀后的图像erode(testImgThresh, erodeSrc,struct1);Mat morphKernel getStructuringElement(MORPH_RECT, Size(3, 3));morphologyEx(erodeSrc, testImgThresh, MORPH_OPEN, morphKernel);morphologyEx(erodeSrc, testImgThresh, MORPH_CLOSE, morphKernel);vectorvectorPoint contours;vectorVec4i hierarchy;findContours(testImgThresh, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);qDebug() — contours:contours.size();if (contours.size() 10){return;}vectorRect digitROIs;for (const auto contour : contours) {Rect bbox boundingRect(contour);// 根据尺寸过滤噪声与无效区域qDebug() — bbox.width:bbox.width;bbox.height:bbox.height;if (bbox.width 20 bbox.height 20 bbox.width 200 bbox.height 200) {digitROIs.push_back(bbox);}}// 3. 分割粘连区域int avgWidth 90; // 假设单个数字的平均宽度可根据实际情况调整for (size_t i 0; i digitROIs.size(); i) {if (digitROIs[i].width 1.5 * avgWidth) { // 判断是否为粘连区域// 提取粘连区域的二值图像Mat roiImg testImgThresh(digitROIs[i]);// 计算垂直投影Mat projection(1, roiImg.cols, CV_32F);reduce(roiImg, projection, 0, REDUCE_SUM, CV_32F);// 寻找分割点局部最小值int splitPos -1;float minVal numeric_limitsfloat::max();for (int j 1; j projection.cols - 1; j) {float val projection.atfloat(0, j);if (val projection.atfloat(0, j - 1) val projection.atfloat(0, j 1) val minVal) {minVal val;splitPos j;}}// 根据分割点分割边界框if (splitPos 0) {Rect leftROI(digitROIs[i].x, digitROIs[i].y, splitPos, digitROIs[i].height);Rect rightROI(digitROIs[i].x splitPos, digitROIs[i].y, digitROIs[i].width - splitPos, digitROIs[i].height);// 替换原始粘连区域digitROIs.erase(digitROIs.begin() i);digitROIs.insert(digitROIs.begin() i, leftROI);digitROIs.insert(digitROIs.begin() i 1, rightROI);i–; // 重新检查新插入的区域}}}// 按 x 坐标排序从左到右sort(digitROIs.begin(), digitROIs.end(), {return a.x b.x;});cout 检测到的轮廓数量: digitROIs.size() endl;for (const auto roi : digitROIs) {cout 边界框: roi endl;}string recognized ;for (const auto roi : digitROIs) {Mat digitROI testImgThresh(roi);Mat digitResized;resize(digitROI, digitResized, Size(digitWidth, digitHeight));vectorfloat descriptors;hog.compute(digitResized, descriptors);Mat sample(1, descriptorSize, CV_32F);for (int j 0; j descriptorSize; j) {sample.atfloat(0, j) descriptors[j];}int predicted (int)svm-predict(sample);recognized.push_back(0 predicted);}QString str QString::fromStdString(recognized);emit SIGNAL_DATA_NUM(str);cout 识别结果1: recognized endl; #endif }InitSVM基本就是训练的标准流程了那么比较核心的还是下面这个函数这个函数HandlerImage可能就需要你进行一些调整 首先先进行基本的图像处理由于某些打印的会出现说数字粘在一起的情况那么就得采用这个分割粘连区域进行局部处理才能分割出来我这份代码试了两种情况都还可以一个是会粘着的一个是不会粘着的。 其他你需要更详细的可以将这两个函数放到AI中帮忙解释一下就可以了。 接下来就到了我们的经典环节 参考 1、opencv 数字识别 数码管