Qt+OpenCV识别物体的形状

1 篇文章 0 订阅

简介:刚开始学习OpenCV的时候,老师布置了一个Qt+OpenCV来识别物体形状的任务。识别的形状主要有矩形、五角星、圆形。

这个是我们要处理的图片381b1621f30c4cf8955ff4eb68be865e.jpeg

 

思路:首先将图片进行一系列的预处理,然后进行轮廓检测,通过轮廓检测来获取每个物体的轮廓面积(即物体面积)设为S1。其次,我们获取每个轮廓对应的最小外接矩形面积S2。最后,我们求取最小外接据徐面积与轮廓面积的比值R。我们通过比值R来判断该物体为什么形状。如矩形的最小外接矩形就是其本身,使用R=1。
下面是具体代码:

 String image_path = "C:\\Users\\86195\\Pictures\\testimg\\*.jpg";  //图片路径
 Mat img,hsv,cloneImg;
 int num_star = 0;int num_white = 0; int num_black = 0;int num_rect= 0;

 img = imread(image_path);
 cloneImg =img.clone();
 cv::resize(img,img,Size(480,640));
 cv::resize(cloneImg,cloneImg,Size(480,640));

 cvtColor(img,hsv,COLOR_BGR2HSV);
 imshow("hsv", hsv);
 vector<Mat> channels;
 split(hsv, channels);//分离HSV
 imshow("channels",channels[2]);
 Canny(channels[2],channels[2],3000,600,5);
 vector<vector<Point>> contours;
 vector<Vec4i> hierachy;
 // 轮廓检测
 findContours(channels[2], contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1,-1));
 vector<RotatedRect> box(contours.size());
 for (size_t i = 0;i<contours.size();i++)  // 遍历获取到的轮廓
               {
                   double area_contour = contourArea(contours[i]);  // 获取该轮廓的面积
                   if(area_contour > 1000 && area_contour<20000)  //因为图片处理原因,难免会有一些干扰因素,所有我们可以使用比较轮廓面积的方法排除一些我们不需要的轮廓或杂质
                   {   // 获取轮廓的最小外接矩形并求出该轮廓与其最小外接矩形的比例
                       box[i] = minAreaRect(Mat(contours[i]));
                       double area_minrect = box[i].size.area();
                       double result =  area_contour/area_minrect;
                      if( result>0.9)  // 矩形的轮廓面积与其最小外接矩形的面积相等,考虑到操作误差,所有我们将比例大于0.9的认为是矩形
                      {
                          qDebug() <<"该物体形状为矩形"<<endl;
                          num_rect++;
                      }
                      if(result<0.9 && result>0.75)  //圆形
                      {
                          // 如果我们想要区分物体是什么颜色的,我们可以去其一点,通过该点的rgb来判断为什么颜色
                          // 这里我们去圆心的像素进行判断
                          int x = box[i].center.x;
                          int y = box[i].center.y;
                          Vec3b intensity =img.at<Vec3b>(y, x);//读一个RGB像素点的像素值
                          int pixel = intensity.val[0]; /*通道0*/
                          if (pixel < 150)  //我们认为通道0像素小于150的为黑色,否则为白色
                          {
                              qDebug() <<"黑圆形"<<endl;
                              num_black++;
                          }
                          else
                          {
                              qDebug() <<"白圆形"<<endl;
                              num_white++;
                          }
                      }
                      if(result>0.3 && result<0.75)  //五角星
                      {
                          num_star++;
                      }
                      drawContours(cloneImg, contours, i, Scalar(0, 255, 0), 3, 8, hierachy);  //画出轮廓
                    }
               }

               qDebug() <<" 白色棋子个数:" <<num_white <<"\n" <<"黑色棋子个数:" <<num_black <<"\n"<<"矩形个数:"<<num_rect<<"\n"<<"五角星个数:"<<num_star;
               qDebug() <<"\n";

这个是效果图:

ab5eb49316ed47a58477c2f35fab7c4f.png

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值