交通标志红孔检测法

来源:互联网 发布:c 动态分配二维数组 编辑:程序博客网 时间:2024/04/29 14:54

哈工大博士王刚毅论文中提到红孔检测法,论文描述其检测效果很好,用opencv实现了一下可能是他描述的不够详细,也可能本人理解有偏差,实现方法不一致,导致我的检测效果很一般。

// Blue.cpp : 定义控制台应用程序的入口点。////#include "stdafx.h"#include <opencv/cv.h>#include <opencv/cxcore.h>#include <opencv/highgui.h>#include <cmath>#include <iostream>#include<vector>#include <imgproc/imgproc.hpp>using namespace std;using namespace cv;#define pi 3.1415926int _tmain(int argc, _TCHAR* argv[]){Mat img =imread("D://转移//交通标志//交通标志数据库//TEMP1//00100.jpg");if (!img.data){return 0;}/*cvNamedWindow("test");imshow("test",img);cvWaitKey(0);*///转到HSVMat  hsv_base;Mat  how_red;cvtColor(img, hsv_base, CV_BGR2HSV );/*cvNamedWindow("hsv");imshow("hsv",hsv_base);cvWaitKey(0);*/Mat colorCut;colorCut.create(img.rows,img.cols,CV_32F);how_red.create(img.rows,img.cols,CV_32F);//颜色分割for(int x=0;x<hsv_base.rows;x++){for(int y=0;y<hsv_base.cols;y++){double h_src=hsv_base.at<Vec3b >(x,y)[0];h_src =h_src/255.0*360;double s_src=hsv_base.at<Vec3b >(x,y)[1];s_src=s_src/255;double v_src= hsv_base.at<Vec3b >(x,y)[2];if ( h_src>=300&&h_src<360){how_red.at<float>(x,y)=s_src*sin((h_src-300.0)/180.0*pi)/sin(60.0/180*pi);}else if (h_src>=0&&h_src<=60){how_red.at<float>(x,y)=s_src*sin((60.0-h_src)/180.0*pi)/sin(60.0/180*pi);}else{    how_red.at<float>(x,y)=0.0;}colorCut.at<float>(x,y)=0;if (h_src>330||(h_src<=30&&s_src>=0.2)){colorCut.at<float>(x,y)=255;}}}double *max_value ;double *min_value ;double  maxVal=0;double  minVal =0;max_value =&maxVal;min_value =&minVal; minMaxLoc(how_red, min_value, max_value);/*cvNamedWindow("how");imshow("how",how_red);cvWaitKey(0);*/////////////////////////////////////////////////////////////////////////////红色位图均值滤波// //红色程度图滤波//Mat blueredImg ;Mat blueredHowRed;blueredImg.create(colorCut.rows,colorCut.cols,CV_32F);blueredHowRed.create(colorCut.rows,colorCut.cols,CV_32F);      colorCut/=255.; blur(colorCut,blueredImg,Size(7,7));  minMaxLoc(blueredImg, min_value, max_value);blur(how_red,blueredHowRed,Size(7,7));//cvNamedWindow("blur");//imshow("blur",blueredImg);//cvWaitKey(0);////////////////////////////////////////////////////////////////////////////得到最终细化后要提取区域的图像Mat RefinedImg(colorCut.rows,colorCut.cols,CV_8UC1);  for (int x =0;x<img.rows;x++){for (int y=0;y<img.cols;y++){double f  =blueredHowRed.at<float>(x,y);double r  = blueredImg.at<float>(x,y);double ff =how_red.at<float>(x,y);if (r>=0.8){RefinedImg.at<uchar>(x,y)=255;}else if (ff>=f&& r<0.8&&r>=0.2){RefinedImg.at<uchar>(x,y)=255;}else{RefinedImg.at<uchar>(x,y)=0;}}}cvNamedWindow("last");    imshow("last",RefinedImg);    cvWaitKey(0);imwrite("RefinedImg.jpg",RefinedImg);////////////////////////////////////////////////////////////////////////////开闭运算//dilate(RefinedImg,RefinedImg,cv::Mat());erode(RefinedImg,RefinedImg,cv::Mat());//dilate(RefinedImg,RefinedImg,cv::Mat());cvNamedWindow("bbbb");imshow("bbbb",RefinedImg);cvWaitKey(0);////////////////////////////////////////////////////////////////////////////提取区域寻找红孔// vector<vector<Point>> contours;   findContours(RefinedImg,           contours, // a vector of contours           CV_RETR_EXTERNAL, // retrieve the external contours          CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours     //筛选区域,太大的太小的去除//    Mat resultt(colorCut.rows,colorCut.cols,CV_8U,Scalar(0));      int cmin= 100;   // minimum contour length      int cmax= 1000; // maximum contour length      vector<vector<Point>>::const_iterator itc= contours.begin();      while (itc!=contours.end()) {            if (itc->size() < cmin || itc->size() > cmax)              itc= contours.erase(itc);          else               ++itc;      }    //////////////////////////////////////////////////////////////////////////    // draw contours on the original image//     //对筛选后的区域求外接多凸边形//   vector<Point> hull;     vector<vector<Point>>::const_iterator itc1=contours.begin();      while (itc1!=contours.end()){                   convexHull(Mat(*itc1),hull);           // Iterate over each segment and draw it             vector<Point>::const_iterator it= hull.begin();              while (it!=(hull.end()-1))         {    line(resultt,*it,*(it+1),Scalar(255),3);    ++it;                }               line(resultt,*(hull.begin()),*(hull.end()-1),Scalar(255),3);                   ++itc1;                   }       vector<vector<Point>> contours2;       findContours(resultt,            contours2, // a vector of contours            CV_RETR_EXTERNAL, // retrieve the external contours           CV_CHAIN_APPROX_NONE);drawContours(resultt,contours2, -1 , Scalar(255),CV_FILLED); //填充区域。//         namedWindow("ddddd");            imshow("ddddd",resultt);       cvWaitKey(0);    minMaxLoc(resultt, min_value, max_value);  cout<<"max:"<<maxVal<<"min:"<<minVal<<endl;    imwrite("resultt.jpg",resultt);//////////////////////////////////////////////////////////////////////////          //显示红孔        Mat Hole(img.rows,img.cols,CV_8UC1);Mat res  =  imread("resultt.jpg",0);Mat refin= imread("RefinedImg.jpg",0);for (int x=0;x<img.rows;x++){for (int y=0;y<img.cols;y++){int rr =res.at<uchar>(x,y);int ff = refin.at<uchar>(x,y);if (rr>ff){Hole.at<uchar>(x,y)=255;} else{Hole.at<uchar>(x,y)=0;}}}erode(Hole,Hole,cv::Mat());    namedWindow("dddd");           imshow("dddd",Hole);     cvWaitKey(0);return 0;}////////////////////////////////////////////////////////////////////////


0 0
原创粉丝点击