超像素提取加svm训练,鼠标点击选择标签(左键为正样本,右键为负样本)

自己写的demo记个笔记用
替换掉图片路径和保存路径svm训练的模型路径就可以跑
效果我觉的不行,目前也不知到如何优化、希望有大佬可以给点建议
流程
处理超像素
选择超像素
提取HOG、颜色直方图、LBP直方图特征
训练
预测

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ximgproc.hpp>
#include <opencv2/ml.hpp>using namespace cv;
using namespace std;
using namespace cv::ml;
Mat g_LabelSlic;  
Mat g_MaskSlic;
int g_NumSuperPixels;//目标图像和标签
multimap<int, Mat>g_mapImgSuperPixelsOfTarget;
multimap<int, Mat>g_mapImgSuperPixelsOfNonTarget;struct MouseCallbackData {Mat img;      // 原始图像Mat imgClone; // 克隆图像
};Mat GetSuperPixelsByLabel(const Mat& img, int superpixelID)
{int minX = img.cols, minY = img.rows, maxX = 0, maxY = 0;for (int y = 0; y < img.rows; y++) {for (int x = 0; x < img.cols; x++) {if (g_LabelSlic.at<int>(y, x) == superpixelID) {// 更新边界框坐标if (x < minX) minX = x;if (y < minY) minY = y;if (x > maxX) maxX = x;if (y > maxY) maxY = y;}}}// 确保边界框有效if (minX > maxX || minY > maxY) {cout << "未找到有效的超像素!" << endl;return Mat();  }Rect superPixelBoundingBox(minX, minY, maxX - minX + 1, maxY - minY + 1);Mat croppedRegion = img(superPixelBoundingBox).clone();  for (int y = 0; y < croppedRegion.rows; y++) {for (int x = 0; x < croppedRegion.cols; x++) {int origX = x + minX;int origY = y + minY;if (g_LabelSlic.at<int>(origY, origX) != superpixelID) {croppedRegion.at<Vec3b>(y, x) = Vec3b(0, 0, 0); }}}return croppedRegion; 
}vector<float> GetHOGDescriptor(Mat img)
{if (img.empty()) {std::cerr << "输入图像为空!" << std::endl;return {};}resize(img, img, Size(64, 64));Mat imgGray;cvtColor(img, imgGray, COLOR_BGR2GRAY);HOGDescriptor hog(Size(32, 32),  // 图像窗口大小Size(8, 8),   // 块大小Size(4, 4),     // 块步长Size(4, 4),     // cell 大小9               // 梯度方向 bins 数);vector<float> descriptors;hog.compute(imgGray, descriptors);return descriptors;
}// 提取 LBP 特征及其直方图
void ExtractLBPFeatures(Mat img, Mat& lbp, Mat& lbpHist)
{resize(img, img, Size(64, 64));// 转换为灰度图Mat gray;if (img.channels() == 3) {cvtColor(img, gray, COLOR_BGR2GRAY);}else {gray = img.clone();}// 初始化 LBP 特征矩阵lbp = Mat(gray.size(), CV_8UC1, Scalar(0));for (int y = 1; y < gray.rows - 1; y++) {for (int x = 1; x < gray.cols - 1; x++) {uchar center = gray.at<uchar>(y, x);uchar code = 0;code |= (gray.at<uchar>(y - 1, x - 1) > center) << 7; // 128code |= (gray.at<uchar>(y - 1, x) > center) << 6;     // 64code |= (gray.at<uchar>(y - 1, x + 1) > center) << 5; // 32code |= (gray.at<uchar>(y, x + 1) > center) << 4;     // 16code |= (gray.at<uchar>(y + 1, x + 1) > center) << 3; // 8code |= (gray.at<uchar>(y + 1, x) > center) << 2;     // 4code |= (gray.at<uchar>(y + 1, x - 1) > center) << 1; // 2code |= (gray.at<uchar>(y, x - 1) > center);           // 1lbp.at<uchar>(y, x) = code; // 将计算的 LBP 值存储}}// 计算 LBP 直方图const int histSize = 256; // LBP 特征值的范围const float range[] = { 0, 256 };const float* histRange = { range };calcHist(&lbp, 1, 0, Mat(), lbpHist, 1, &histSize, &histRange);normalize(lbpHist, lbpHist);
}Mat ExtractHSVHistogram(Mat img)
{resize(img, img, Size(64, 64));Mat hsv_img;cvtColor(img, hsv_img, cv::COLOR_BGR2HSV); vector<cv::Mat> hsv_planes;split(hsv_img, hsv_planes);  // 分割 H, S, V 通道int histSize = 256;  // 直方图分为 256 个区间float h_range[] = { 0, 180 };  // H 通道范围是 0-180float s_v_range[] = { 0, 256 };  // S 和 V 通道范围是 0-256const float* h_histRange = { h_range };const float* sv_histRange = { s_v_range };Mat h_hist, s_hist, v_hist;calcHist(&hsv_planes[0], 1, 0, cv::Mat(), h_hist, 1, &histSize, &h_histRange, true, false);  // H 通道直方图calcHist(&hsv_planes[1], 1, 0, cv::Mat(), s_hist, 1, &histSize, &sv_histRange, true, false);  // S 通道直方图calcHist(&hsv_planes[2], 1, 0, cv::Mat(), v_hist, 1, &histSize, &sv_histRange, true, false);  // V 通道直方图// 合并 H, S, V 直方图Mat hist;hconcat(h_hist, s_hist, hist);hconcat(hist, v_hist, hist);Mat normalizedHist;normalize(hist, normalizedHist);return normalizedHist;  // 返回归一化后的直方图
}void OnMouse(int event, int x, int y, int flags, void* param)
{MouseCallbackData* data = static_cast<MouseCallbackData*>(param);Mat& img = data->img;Mat& imgClone = data->imgClone;int mouseButtonClicked = 0;if (event == EVENT_LBUTTONDOWN) {mouseButtonClicked = 1;if (x >= 0 && x < img.cols && y >= 0 && y < img.rows) {int superpixelID = g_LabelSlic.at<int>(y, x);cout << "点击目标超像素ID: " << superpixelID << endl;g_mapImgSuperPixelsOfTarget.insert({ mouseButtonClicked, GetSuperPixelsByLabel(img, superpixelID) });circle(imgClone, Point(x, y), 3, Scalar(0, 255, 0), -1);imshow("Imageview", imgClone);}}else if (event == EVENT_RBUTTONDOWN) {mouseButtonClicked = 2;if (x >= 0 && x < img.cols && y >= 0 && y < img.rows) {int superpixelID = g_LabelSlic.at<int>(y, x);cout << "点击非目标超像素ID: " << superpixelID << endl;g_mapImgSuperPixelsOfNonTarget.insert({ mouseButtonClicked, GetSuperPixelsByLabel(img, superpixelID) });circle(imgClone, Point(x, y), 3, Scalar(0, 0, 255), -1);imshow("Imageview", imgClone);}}
}void SvmClassifier(multimap<int, vector<float>> HOGDescriptorOFTarget,multimap<int, Mat> lbpHistOFTarget,multimap<int, Mat> hsvHistOFTarget,multimap<int, vector<float>> HOGDescriptorOFNonTarget,multimap<int, Mat> lbpHistOFNonTarget,multimap<int, Mat> hsvHistOFNonTarget)
{cout << "star svm model train ..." << endl;Mat featureList;Mat labels;for (const auto& pair : HOGDescriptorOFTarget) {Mat hogMat(pair.second, CV_32F);normalize(hogMat, hogMat, 0, 1, NORM_MINMAX);hogMat = hogMat.reshape(1, 1);Mat lbpHist = lbpHistOFTarget.find(pair.first)->second;lbpHist.convertTo(lbpHist, CV_32F);lbpHist = lbpHist.reshape(1, 1);  // 展平Mat hsvHist = hsvHistOFTarget.find(pair.first)->second;hsvHist.convertTo(hsvHist, CV_32F);hsvHist = hsvHist.reshape(1, 1);  // 展平Mat combinedFeature;hconcat(hogMat, lbpHist, combinedFeature);  hconcat(combinedFeature, hsvHist, combinedFeature);  featureList.push_back(combinedFeature);labels.push_back(1); }for (const auto& pair : HOGDescriptorOFNonTarget) {Mat hogMat(pair.second, CV_32F);normalize(hogMat, hogMat, 0, 1, NORM_MINMAX); hogMat = hogMat.reshape(1, 1);Mat lbpHist = lbpHistOFNonTarget.find(pair.first)->second;lbpHist.convertTo(lbpHist, CV_32F);lbpHist = lbpHist.reshape(1, 1); Mat hsvHist = hsvHistOFNonTarget.find(pair.first)->second;hsvHist.convertTo(hsvHist, CV_32F);hsvHist = hsvHist.reshape(1, 1); Mat combinedFeature;hconcat(hogMat, lbpHist, combinedFeature);hconcat(combinedFeature, hsvHist, combinedFeature);featureList.push_back(combinedFeature);labels.push_back(0);  }Mat trainingData;vconcat(featureList, trainingData); //Mat labelsMat;// = Mat(labels).reshape(1, 1);Mat labelsMat = labels;trainingData.convertTo(trainingData, CV_32F);labelsMat.convertTo(labelsMat, CV_32S);Ptr<SVM> svm = SVM::create();svm->setKernel(SVM::RBF);svm->setType(SVM::C_SVC);svm->trainAuto(trainingData,ROW_SAMPLE,labelsMat,10);/*svm->setC(1.5);svm->setGamma(0.5);svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 200, 1e-6));svm->train(trainingData, ROW_SAMPLE, labelsMat);*/svm->save("C:/Users/svs/Desktop/svm_model2.xml"); // 保存训练好的模型
}void DrawSuperpixelRegion(Mat& img, int targetLabel) {for (int y = 0; y < img.rows; y++) {for (int x = 0; x < img.cols; x++) {if (g_LabelSlic.at<int>(y, x) == targetLabel) {img.at<Vec3b>(y, x) = Vec3b(0, 255, 0); }}}
}int main() {Mat img = imread("C:/Users/svs/Desktop/test.jpeg");if (img.empty()) {cerr << "无法读取图片!" << endl;return -1;}//图片进行超像素分割int region_size = 50;float ruler = 20.0;int num_iterations = 100;Ptr<ximgproc::SuperpixelSLIC> slic = ximgproc::createSuperpixelSLIC(img, ximgproc::SLICO,region_size, ruler);slic->iterate(num_iterations);slic->getLabels(g_LabelSlic);slic->getLabelContourMask(g_MaskSlic);g_NumSuperPixels = slic->getNumberOfSuperpixels();Mat imgWithContours;img.copyTo(imgWithContours, ~g_MaskSlic);imshow("Superpixel Contours", imgWithContours);cout << "请点击选择一个超像素区域...\n";namedWindow("Imageview", WINDOW_AUTOSIZE);imshow("Image", img);Mat imgClone = img.clone();imshow("Imageview", imgClone);MouseCallbackData data;data.img = img;data.imgClone = imgClone;setMouseCallback("Imageview", OnMouse, &data);// 等待用户按 'q' 退出while (true) {const char key = waitKey(0);if (key == 'q') {break;}}/*提取获取图片的特征*/multimap<int, vector<float> >HOGDescriptorOFTarget;multimap<int, Mat >lbpHistOFTarget;multimap<int, Mat >hsvHistOFTarget;multimap<int, vector<float> >HOGDescriptorOFNonTarget;multimap<int, Mat>lbpHistOFNonTarget;multimap<int, Mat>hisHistOFNonTarget;for (const auto& pair : g_mapImgSuperPixelsOfTarget) {vector<float> vectorHOGDescriptor = GetHOGDescriptor(pair.second);HOGDescriptorOFTarget.insert({ pair.first, vectorHOGDescriptor});Mat lbpImg, lbpHist;ExtractLBPFeatures(pair.second, lbpImg, lbpHist);lbpHistOFTarget.insert({ pair.first, lbpHist });Mat hsvHist;hsvHist = ExtractHSVHistogram(pair.second);hsvHistOFTarget.insert({ pair.first,hsvHist });/*imshow("true", pair.second);waitKey(0);*/}for (const auto& pair : g_mapImgSuperPixelsOfNonTarget){vector<float> vectorHOGDescriptor = GetHOGDescriptor(pair.second);HOGDescriptorOFNonTarget.insert({ pair.first,vectorHOGDescriptor });Mat lbpImg, lbpHist;ExtractLBPFeatures(pair.second, lbpImg, lbpHist);lbpHistOFNonTarget.insert({ pair.first, lbpHist });Mat hsvHist;hsvHist = ExtractHSVHistogram(pair.second);hisHistOFNonTarget.insert({ pair.first,hsvHist});/* imshow("false", pair.second);waitKey(0);*/}SvmClassifier(HOGDescriptorOFTarget, lbpHistOFTarget, hsvHistOFTarget,HOGDescriptorOFNonTarget,lbpHistOFNonTarget, hisHistOFNonTarget);Ptr<SVM> svm = SVM::load("C:/Users/svs/Desktop/svm_model2.xml");if (svm.empty()) {std::cerr << "模型加载失败!\n";return -1;}//进行预测cout << "star predict ...\n";multimap<int, Mat> testSuperPixelsImg;vector<float> testHOGDescriptor;Mat testLbpHist;Mat testHsvHist;// 遍历每个超像素块for (int superpixelID = 0; superpixelID < g_NumSuperPixels; ++superpixelID) {Mat superpixelRegion = GetSuperPixelsByLabel(img, superpixelID);testSuperPixelsImg.insert({ superpixelID,  superpixelRegion });}for (const auto& pairs : testSuperPixelsImg) {/*imshow("test", pairs.second);waitKey(0);*/testHOGDescriptor = GetHOGDescriptor(pairs.second);Mat lbpImg;ExtractLBPFeatures(pairs.second, lbpImg,testLbpHist);testHsvHist = ExtractHSVHistogram(pairs.second);if (testHOGDescriptor.empty()){cerr << "HOG特征为空,超像素ID: \n";}if (testLbpHist.empty()){cerr << "LBP特征为空,超像素ID: \n";}if(testHsvHist.empty()){cerr << "Hsv直方图为空,超像素ID:\n";}Mat testHogMat(testHOGDescriptor, CV_32F);normalize(testHogMat, testHogMat, 0, 1, NORM_MINMAX);testHogMat = testHogMat.reshape(1, 1);testLbpHist.convertTo(testLbpHist, CV_32F);testLbpHist = testLbpHist.reshape(1, 1);  testHsvHist.convertTo(testHsvHist, CV_32F);testHsvHist = testHsvHist.reshape(1, 1);  Mat combinedFeature;hconcat(testHogMat, testLbpHist, combinedFeature);hconcat(combinedFeature, testHsvHist, combinedFeature);// 进行预测float response;response = svm->predict(combinedFeature);if (response == 1) {}else {DrawSuperpixelRegion(img, pairs.first);}}imshow("Image with Green Superpixel", img);cout << "predict successful\n";waitKey(0);destroyAllWindows();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1559371.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos作为注册中心和配置中心

下载安装Nacos 下载地址&#xff1a;Nacos 下载后将这个.zip文件解压 windows系统双击运行startup.cmd 注意事项 一些较新的版本可能会启动时闪退&#xff0c;解决方法为记事本编辑startuo.cmd文件 修改set MODE "standalone" Nacos注册中心 引入依赖 <dep…

动态规划算法专题(六):回文串问题

目录 1、回文子串&#xff08;"引子题"&#xff09; 1.1 算法原理 1.2 算法代码 2、最长回文子串 2.1 算法原理 2.2 算法代码 3、分割回文串 IV&#xff08;hard&#xff09; 3.1 算法原理 3.2 算法代码 4、分割字符串 II&#xff08;hard&#xff09; 4…

Spring Boot教学资源库:开发者的成长之路

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

AI视频技术复活老照片-简单快捷

准备老照片 可在网上搜索“老照片”图片&#xff0c;选择人物背景全的图片 照片修复 腾讯的ARC Lab网站 https://arc.tencent.com/zh/ai-demos/faceRestoration 上传照片&#xff0c;修复后下载&#xff0c;会直接在浏览器中下载 AI视频生成 采用可灵网&#xff1a; http…

PGMP-05相关方

目录 1.主要内容 2.概括 3.相关方人员 1.主要内容 Stakeholders IdentificationStakeholders AnalysisStakeholders Engagement PlanningStakeholders EngagementStakeholder communications 2.概括 识别&#xff1a;产生相关方登记册&#xff0c;使用头脑风暴分析&#x…

深入理解Transformer的笔记记录(精简版本)----Seq2Seq → Seq2Seq with Attention

只要是符合类似的框架,都可以统称为 Encoder-Decoder 模型。 1、RNN RNN引入了隐状态h(hidden state)的概念,隐状态h可以对序列形的数据提取特征,接着再转换为输出。 x1,x2,x3,x4如: 自然语言处理问题。x1可以看做是第一个单词,x2可以看做是第二个单词,依次类推语音处…

2024 闽盾杯-黑盾赛道WP

CRYPTO 签到题-学会SM https://www.json.cn/encrypt/sm3 题目要求小写所以需要转换一下 或者脚本&#xff1a; import hashlib message "heidun2024" hash_object hashlib.new(sm3) hash_object.update(message.encode(utf-8)) hash_value hash_object.hexdigest(…

AI助力智慧农田作物病虫害监测,基于YOLOv9全系列【yolov9/t/s/m/c/e】参数模型开发构建花田作物种植场景下棉花作物常见病虫害检测识别系统

智慧农业是一个很大的应用市场&#xff0c;将当下如火如荼的AI模型技术与现实的农业生产场景相结合能够有效提升生产效率&#xff0c;农作物在整个种植周期中有很多工作需要进行&#xff0c;如&#xff1a;浇水、施肥、除草除虫等等&#xff0c;传统的农业作物种植生产管理周期…

带你走近CCV(一)

从事多媒体互动行业8年了&#xff0c;最近才想着自己可以独自写一个识别软件&#xff0c;应该说想把公司里的识别统统临摹一遍&#xff0c;这样在接外包的时候可以游刃有余了 什么是CCV&#xff1f; CCV是一个建立在openCV基础上的一个开源的架构&#xff0c;其全称是Communit…

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(多数据源配置)

SpringBoot教程&#xff08;二十四&#xff09; | SpringBoot实现分布式定时任务之Quartz&#xff08;多数据源配置&#xff09; 前言多数据源配置引入aop依赖1. properties配置多数据源2. 创建数据源枚举类3. 线程参数配置类4. 数据源动态切换类5. 多数据源配置类HikariCP 版本…

Java基础(2) 之面向对象

文章目录 Java基础(2) 之面向对象1.对象2.类类的注意事项 3.this关键字4.构造器注意 5.封装性6.实体JavaBean实体类 7.成员变量和局部变量的区别8.staticstatic修饰成员变量static修饰成员方法static的注意事项工具类单例设计模式 9.代码块静态代码块实例代码块 10.继承权限修饰…

Springboot——使用poi实现excel动态图片导入解析

文章目录 前言依赖引入导入实现方式一方式二 前言 最近要实现一个导入导出的功能点&#xff0c;需要能将带图片的列表数据导出到excel中&#xff0c;且可以导入带图片的excel列表数据。 考虑到低代码平台的表头与数据的不确定性&#xff0c;技术框架上暂定使用Apache-POI。 …

java 自定义填充excel并导出

首先在resources下面放一个excel模板 1. 方法签名和请求映射 RequestMapping(value "/ExportXls") public ResponseEntity<byte[]> rwzcExportXls(HttpServletRequest request, RequestBody JSONArray jsonArray) throws IOException { RequestMapping(val…

ubuntu 开放 8080 端口快捷命令

文章目录 查看防火墙状态开放 80 端口开放 8080 端口开放 22端口开启防火墙重启防火墙**使用 xhell登录**&#xff1a; 查看防火墙状态 sudo ufw status [sudo] password for crf: Status: inactivesudo ufw enable Firewall is active and enabled on system startup sudo…

微服务实战——登录(普通登录、社交登录、SSO单点登录)

登录 1.1. 用户密码 PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r memberFeignService.login(vo);if(r.getCode() 0){MemberRespVo data r.getData("data", new Type…

进阶功法:SQL 优化指南

目录标题 SQL 优化指南1. 插入数据优化1.1 批量插入数据1.2 手动提交事务1.3 主键顺序插入1.4 大批量插入数据步骤&#xff1a; 2. 主键优化主键设计原则拓展知识 3. ORDER BY 优化3.1 Using filesort3.2 Using index示例 3.3 ORDER BY 优化原则 4. GROUP BY 优化示例 4.1 GROU…

优雅的实现服务调用 -- OpenFeign

文章目录 1. RestTemplate存在问题2. OpenFeign介绍3. 快速上手引入依赖添加注解编写OpenFeign的客户端远程调用 4. OpenFeign参数传递从URL中获取参数传递单个参数传递多个参数传递对象传递JSON 5. 最佳实践Feign继承方式创建一个新的模块引入依赖编写接口打jar包服务实现方实…

javacpp调用pdfium的c++动态库

1、.h头文件 2、生成java代码的conf PdfiumDocumentConfigure.java package org.swdc.pdfium.conf;import org.bytedeco.javacpp.annotation.Platform; import org.bytedeco.javacpp.annotation.Properties; import org.bytedeco.javacpp.tools.InfoMap; import org.byte…

物联网:一种有能力重塑世界的技术

物联网&#xff08;IoT&#xff09;近年来对我们的日常生活产生了如此积极的影响&#xff0c;以至于即使是不懂技术的人也开始相信它所带来的便利以及敏锐的洞察力。 物联网是一场数字技术革命&#xff0c;其意义甚至比工业革命更为重大。物联网是仍处于起步阶段的第四次工业革…

SldWorks问题 2. 矩阵相关接口使用上的失误

问题 在计算三维点在图纸&#xff08;DrawingDoc&#xff09;中的位置时&#xff0c;就是算不对&#xff0c;明明就4、5行代码&#xff0c;怎么看都是很“哇塞”的&#xff0c;毫无问题的。 但结果就是不对。 那就调试一下吧&#xff0c;调试后发现生成的矩阵很不对劲&#…