定制设计的网站,网站做淘宝客收入咋样,做网络销售哪些网站比较好,周末游做的好的网站目录 一、工具
二、原理
概念
本质
三、实践 添加发布话题
主要代码
四、成果
五、总结 一、工具
opencvros
ubuntu18.04
摄像头
二、原理
概念
彩色图像#xff1a;RGB#xff08;红#xff0c;绿#xff0c;蓝#xff09;
HSV图像#xff1a;H#xff0…目录 一、工具
二、原理
概念
本质
三、实践 添加发布话题
主要代码
四、成果
五、总结 一、工具
opencvros
ubuntu18.04
摄像头
二、原理
概念
彩色图像RGB红绿蓝
HSV图像H色调S饱和度V亮度 色调Hhue用角度度量取值范围为0°360°从红色开始按逆时针方向计算红色为0°绿色为120°,蓝色为240°。它们的补色是黄色为60°青色为180°,品红为300° 饱和度Ssaturation取值范围为0.01.0值越大颜色越饱和。 亮度Vvalue取值范围为0(黑色)255(白色)。 但是在opencv中引用的范围有所不同给出下表。 本质
颜色识别本质就是在图像上提取出你想要的颜色阈值然后通过降噪优化模型轮廓检测进行框选。 要点 RGB转HSV所需颜色阈值hsv并二值化腐蚀操作除噪Canny算法进行边缘检测最后通过findContours函数找出轮廓坐标 三、实践
读取摄像头 VideoCapture cap(video_device); //dev/video0RGB转HSV
cvtColor(frame, imghsv, COLOR_BGR2HSV);
直方图均衡化
split(imghsv, hsvSplit);
equalizeHist(hsvSplit[2], hsvSplit[2]);
merge(hsvSplit, imghsv); 直方图均衡化是一种简单有效的图像增强技术,用于增强动态范围偏小的图像的对比度 定义颜色阈值这里选取红色 Scalar lower_red(156, 43, 46);Scalar upper_red(180, 255, 255); // 定义红色的HSV范围inRange(imghsv, lower_red, upper_red, mask);//二值化红色部分inRange()函数就是检测imghsv内所有像素是否在lower-upper之间如果是则设为255也就是白色。输出的是二值图。 用腐蚀膨胀操作去噪点 Mat kernel getStructuringElement(MORPH_RECT, Size(3, 3));morphologyEx(mask, mask, MORPH_OPEN, kernel);//开运算morphologyEx(mask, mask, MORPH_CLOSE, kernel);//闭运算 腐蚀膨胀操作的对象是二值化图像 腐蚀变精细膨胀变粗矿开运算先腐蚀后膨胀 消去一个黑图中的很多小白点闭运算先膨胀后腐蚀 消去一个白图中的很多小黑点梯度运算膨胀-腐蚀 高斯滤波Canny边缘检测 GaussianBlur(mask, mask, Size(3, 3), 0);//高斯滤波Canny(mask, mask, 100, 250);//canny算子边缘检测 Canny函数参数表明 第一个InputArray类型的image输入图像 第二个OutputArray类型的edges输出的边缘图 第三个double类型的threshold1第一个滞后性阈值 第四个double类型的threshold2第二个滞后性阈值 Canny过程为 高斯滤波获得平滑图像计算每个像素点的梯度强度和方向应用非极大值抑制消除边缘检测带来的杂散响应双阈值确定真实或潜在的边缘抑制弱化边缘完成边缘检测 然后开始找轮廓
findContours()函数
findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point()); 第一个参数输入图像 第二个参数所有轮廓 第三个参数表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号 第四个参数RETR_EXTERNAL只检测最外围轮廓 第五个参数CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息 寻找最大轮廓 vectordouble Area(contours.size());//寻找最大面积的轮廓for (int i 1; i contours.size(); i) {Area[i] contourArea(contours[i]);if (Area[i] Area[max]) {max i;} }Rect boundRect boundingRect(Mat(contours[max]));circle(frame, Point(boundRect.x boundRect.width/2, boundRect.y boundRect.height/2), 5, Scalar(0,0,255), -1);
boundingRect()函数 表示包围轮廓的最大矩形 返回四个参数 第一个boundRect.x 第二个boundRect.y 第三个boundRect.width 第四个boundRect.hight 左上角顶点的像素坐标值及矩形边界的宽和高 然后将矩形在原画面画出即可
ROS_INFO(x:%d,y:%d,boundRect.x boundRect.width/2, boundRect.y boundRect.height/2);
rectangle(frame, Point(boundRect.x, boundRect.y), Point(boundRect.x boundRect.width, boundRect.y boundRect.height), Scalar( 0, 0, 255), 2); 添加发布话题
毕竟是在ros下编写的我们要把像素坐标发布出去,这里自定义一个消息类型 boundingbox.msg 用来表示类和坐标值
主要代码 while (ros::ok()) { cap frame; //摄像头画面赋给frameif(!frame.empty()) //画面是否正常{ /*对图片二次处理*/cvtColor(frame, imghsv, COLOR_BGR2HSV);// 将图像转换为HSV颜色空间split(imghsv, hsvSplit);equalizeHist(hsvSplit[2], hsvSplit[2]);merge(hsvSplit, imghsv);inRange(imghsv, lower_red, upper_red, mask);//二值化红色部分Mat kernel getStructuringElement(MORPH_RECT, Size(5, 5));morphologyEx(mask, mask, MORPH_OPEN, kernel);//开运算morphologyEx(mask, mask, MORPH_CLOSE, kernel);//闭运算GaussianBlur(mask, mask, Size(5, 5), 0);//高斯滤波Canny(mask, mask, 150, 100);//canny算子边缘检测vectorvectorPoint contours;vectorVec4i hierarchy;findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point()); //ROS_INFO(个数为%d,int(contours.size()));vectordouble Area(contours.size());if(contours.size() 0 ){//寻找最大面积的轮廓for (int i 1; i contours.size(); i) {Area[i] contourArea(contours[i]);if (Area[i] Area[max]) {max i;} }Rect boundRect boundingRect(Mat(contours[max]));circle(frame, Point(boundRect.x boundRect.width/2, boundRect.y boundRect.height/2), 5, Scalar(0,0,255), -1);ROS_INFO(x:%d,y:%d,boundRect.x boundRect.width/2, boundRect.y boundRect.height/2);rectangle(frame, Point(boundRect.x, boundRect.y), Point(boundRect.x boundRect.width, boundRect.y boundRect.height), Scalar( 0, 0, 255), 2);detect_msg.Class red;detect_msg.xmin boundRect.x;detect_msg.xmaxboundRect.x boundRect.width;detect_msg.yminboundRect.y;detect_msg.ymax boundRect.y boundRect.height;}
四、成果
运行画面 查看话题 这里识别画面内所有红色区域
五、总结
写代码过程中还是遇到很多问题的不知道是opencv版本不兼容的问题还是哪里我编写不细致节点总是挂掉。
但还是能完成基本需求。
这里把报错留下希望有大佬能帮帮我 OpenCV Error: Assertion failed (npoints 0 (depth CV_32F || depth CV_32S)) in pointSetBoundingRect, file /build/opencv-L2vuMj/opencv-3.2.0dfsg/modules/imgproc/src/shapedescr.cpp, line 466 terminate called after throwing an instance of cv::Exception what(): /build/opencv-L2vuMj/opencv-3.2.0dfsg/modules/imgproc/src/shapedescr.cpp:466: error: (-215) npoints 0 (depth CV_32F || depth CV_32S) in function pointSetBoundingRect 应该是boundingRect()函数的问题但不知道问题在哪
欢迎评论区指正。