opencv 颜色识别hsv方法 C++(红色)
时间:2023-03-21
本文章向大家介绍opencv 颜色识别hsv方法 C++(红色),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本文采用的是hsv的方式进行颜色识别,主要流程如下:
- 读取视频 :VideoCapture cap(0);
- 设置图像参数:cap.set(cv::CAP_PROP_FRAME_WIDTH, width);设置图像宽度。
- 将图像转换为HSV颜色空间:cvtColor(frame, hsv, COLOR_BGR2HSV)
- 调整hsv的范围
- 对图像进行二值化处理 inRange(hsv, lower_yellow, upper_yellow, mask);
- 对二值化后的图像进行形态学处理,去除噪点:
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
morphologyEx(mask2, mask2, MORPH_OPEN, kernel);
morphologyEx(mask2, mask2, MORPH_CLOSE, kernel); - 高斯滤波:GaussianBlur(mask2, mask2, Size(3, 3), 0);
- canny算子边缘检测:Canny(mask2, mask2, 100, 250);
- 在二值化后的图像中寻找轮廓
- 计算轮廓的面积
- 寻找面积最大的部分
- 绘制轮廓的最小外接正矩形
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> #include <vector> using namespace cv; using namespace std; int width = 800; // 设置图像宽度 int height = 600; // 设置图像高度 //readme 可以识别红色hsv int main() { VideoCapture cap(0);//读取视频0 cap.set(cv::CAP_PROP_FRAME_WIDTH, width); // 设置图像宽度 cap.set(cv::CAP_PROP_FRAME_HEIGHT, height); // 设置图像高度 while (true) { int max = 0; Mat frame; cap.read(frame); Mat hsv; cvtColor(frame, hsv, COLOR_BGR2HSV);// 将图像转换为HSV颜色空间 cv::Scalar lower_yellow(7, 94, 82); cv::Scalar upper_yellow(54, 232, 255); // 定义黄色的HSV范围 cv::Scalar lower_red(137, 144, 114); cv::Scalar upper_red(255, 241, 242); // 定义红色的HSV范围 Mat mask; Mat mask2; inRange(hsv, lower_yellow, upper_yellow, mask);// 对图像进行二值化,只保留蓝色部分 inRange(hsv, lower_red, upper_red, mask2); // 对二值化后的图像进行形态学处理,去除噪点 Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5)); morphologyEx(mask2, mask2, MORPH_OPEN, kernel); morphologyEx(mask2, mask2, MORPH_CLOSE, kernel); GaussianBlur(mask2, mask2, Size(3, 3), 0);//高斯滤波 Canny(mask2, mask2, 100, 250);//canny算子边缘检测 // 在二值化后的图像中寻找轮廓 vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(mask2, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); Mat mask2Contours = Mat::zeros(mask2.size(), CV_8UC1); Mat Contours = Mat::zeros(mask2.size(), CV_8UC1); Mat mask2Contours0 = Mat::zeros(mask2.size(), CV_8UC1); vector<double> g_dConArea(contours.size()); for (int i = 0; i < contours.size(); i++) { //contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数 for (int j = 0; j < contours[i].size(); j++) { //绘制出contours向量内所有的像素点 //Point P = Point(contours[i][j].x, contours[i][j].y); //Contours.at<uchar>(P) = 255; //计算轮廓的面积 g_dConArea[i] = contourArea(contours[i]); } //寻找面积最大的部分 for (int i = 1; i < contours.size(); i++) { if (g_dConArea[i] > g_dConArea[max]) { max = i; } } } //Point pt1(200, 100); //Point pt2(600, 500); drawContours(mask2Contours, contours, max, Scalar(255), 1, 8, hierarchy); //绘制轮廓的最小外接正矩形 Rect boundRect = boundingRect(Mat(contours[max])); rectangle(mask2Contours0, Point(boundRect.x, boundRect.y), Point(boundRect.x + boundRect.width, boundRect.y + boundRect.height), Scalar(255), 2, 8); //中心点Point(boundRect.x+boundRect.width/2,boundRect.y+boundRect.height/2); //绘制轮廓的最小外结矩形 circle(frame, Point(boundRect.x + boundRect.width/2, boundRect.y + boundRect.height/2), 5, Scalar(255), -1); RotatedRect rect = minAreaRect(contours[max]); Point2f P[4];//初始化矩形四个顶点坐标 rect.points(P); for (int j = 0; j <= 3; j++) { line(mask2Contours, P[j], P[(j + 1) % 4], Scalar(255), 2); line(frame, P[j], P[(j + 1) % 4], Scalar(255), 2); } if (waitKey(1) == 'q') break; imshow("hsv", hsv); imshow("mask", mask); imshow("mask2", mask2); /*imshow("contours", contours);*/ imshow("Color Detection", frame); imshow("最小正外接矩形", mask2Contours0); imshow("Contours Image", mask2Contours); //轮廓 //imshow("Point of Contours", Contours); //向量contours内保存的所有轮廓点集 } // 释放摄像头资源和所有窗口 cap.release(); destroyAllWindows(); return 0; }
写的垃圾,大佬多多指教。
- 效果图1:
-
颜色随便提取的(大家也可以尝试用提取通道的方法)
原文地址:https://www.cnblogs.com/shlmqq/p/17238567.html
- Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
- 关于curl网站运维与开发的那些事
- 并查集Union-find及其在最小生成树中的应用
- go 语言的库文件放在哪里?如何通过nginx代理后还能正确获取远程地址
- 离线Tarjan算法-最近公共祖先问题
- Java文件上传下载实训
- 【网络编程系列】二:socket通信原理及实践
- textrank算法原理与提取关键词、自动提取摘要PYTHON
- 【网络编程系列】一:字节顺序的大端与小端表示法
- Linux下的make命令用法
- 增量数据丢失的原因分析(三)(r8笔记第91天)
- JS之浏览器对象BOM
- 超清晰的makefile解释、编写与示例
- 一个简单的sql审核案例 (r8笔记第90天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JavaWeb - Linux Operating System
- 第三章--第六节:元祖
- JavaWeb - 开发环境搭建和 Shell 编程
- 第四章--第一节:函数
- 教育平台项目后台管理系统:接口文档
- 第四章--第二节:类
- 教育平台项目后台管理系统:介绍与搭建
- Python办公自动化之Excel做表自动化:全网最全,看这一篇就够了!
- Java学习笔记-spring-Bean实例化
- Java学习笔记-spring-Bean作用于
- 教育平台项目后台管理系统:课程信息模块
- 教育平台项目后台管理系统:课程内容模块
- 100 个 Python 小例子
- Entity Framework初体验
- Entity Framework 小知识(一)