OpenCV摄像头简单程序
无论是处理现有视频文件还是实时读取摄像头,其实都是读取连续的帧(frame)。每个frame都可以看做是一个图像(Mat),图像处理的方式就可以用在video的处理上了。现在,动手试一试。
【代码1】用霍夫变换(Hough Transform)检测直线并且显示在实时video中
1 #include <cv.h> 2 #include <highgui.h> 3 #include <iostream> 4 #include <vector> 5 6 using namespace std; 7 using namespace cv; 8 9 #define PI 3.1415926 10 11 class LineFinder{ 12 private: 13 Mat img; 14 vector<Vec4i>lines; 15 double deltaRho; 16 double deltaTheta; 17 int minVote; 18 double minLength; 19 double maxGap; 20 public: 21 LineFinder():deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.){} 22 23 void setAccResolution(double dRho, double dTheta){ 24 deltaRho=dRho; 25 deltaTheta=dTheta; 26 } 27 void setMinVote(int minv){ 28 minVote=minv; 29 } 30 void setLineLengthAndGap(double length, double gap){ 31 minLength=length; 32 maxGap=gap; 33 } 34 vector<Vec4i>findLines(Mat& binary){ 35 lines.clear(); 36 HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap); 37 return lines; 38 } 39 void drawDetectedLines(Mat &image, Scalar color=Scalar(255, 255, 255)){ 40 vector<Vec4i>::const_iterator it2=lines.begin(); 41 while(it2!=lines.end()){ 42 Point pt1((*it2)[0], (*it2)[1]); 43 Point pt2((*it2)[2], (*it2)[3]); 44 line(image, pt1, pt2, color); 45 ++it2; 46 } 47 } 48 }; 49 50 int main(){ 51 52 53 string msg="press q , Q or ESC to close this program"; 54 cout << msg << endl; 55 VideoCapture capture(0); 56 if(!capture.isOpened()) return 1; 57 Mat image; //frame of video 58 string window_name="Extracted Frame"; 59 namedWindow(window_name); 60 while(true){ 61 capture >> image; 62 if(image.data){ 63 Mat contours; 64 Canny(image, contours, 125, 350); 65 LineFinder finder; 66 finder.setLineLengthAndGap(100, 20); 67 finder.setMinVote(80); 68 vector<Vec4i>lines=finder.findLines(contours); 69 finder.drawDetectedLines(image); 70 namedWindow("Detected Lines with HoughP"); 71 imshow("Detected Lines with HoughP", image); 72 } 73 if(waitKey(30)>=0) break; 74 } 75 76 77 return 0; 78 }
【代码2】矩形检测
1 // The "Square Detector" program. 2 // It loads several images sequentially and tries to find squares in 3 // each image 4 5 #include "opencv2/core/core.hpp" 6 #include "opencv2/imgproc/imgproc.hpp" 7 #include "opencv2/highgui/highgui.hpp" 8 9 #include <iostream> 10 #include <math.h> 11 #include <string.h> 12 13 using namespace cv; 14 using namespace std; 15 16 static void help() 17 { 18 cout << 19 "\nA program using pyramid scaling, Canny, contours, contour simpification and\n" 20 "memory storage (it's got it all folks) to find\n" 21 "squares in a list of images pic1-6.png\n" 22 "Returns sequence of squares detected on the image.\n" 23 "the sequence is stored in the specified memory storage\n" 24 "Call:\n" 25 "./squares\n" 26 "Using OpenCV version %s\n" << CV_VERSION << "\n" << endl; 27 } 28 29 30 int thresh = 50, N = 11; 31 const char* wndname = "Square Detection Demo"; 32 33 // helper function: 34 // finds a cosine of angle between vectors 35 // from pt0->pt1 and from pt0->pt2 36 static double angle( Point pt1, Point pt2, Point pt0 ) 37 { 38 double dx1 = pt1.x - pt0.x; 39 double dy1 = pt1.y - pt0.y; 40 double dx2 = pt2.x - pt0.x; 41 double dy2 = pt2.y - pt0.y; 42 return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); 43 } 44 45 // returns sequence of squares detected on the image. 46 // the sequence is stored in the specified memory storage 47 static void findSquares( const Mat& image, vector<vector<Point> >& squares ) 48 { 49 squares.clear(); 50 51 Mat pyr, timg, gray0(image.size(), CV_8U), gray; 52 53 // down-scale and upscale the image to filter out the noise 54 pyrDown(image, pyr, Size(image.cols/2, image.rows/2)); 55 pyrUp(pyr, timg, image.size()); 56 vector<vector<Point> > contours; 57 58 // find squares in every color plane of the image 59 for( int c = 0; c < 3; c++ ) 60 { 61 int ch[] = {c, 0}; 62 mixChannels(&timg, 1, &gray0, 1, ch, 1); 63 64 // try several threshold levels 65 for( int l = 0; l < N; l++ ) 66 { 67 // hack: use Canny instead of zero threshold level. 68 // Canny helps to catch squares with gradient shading 69 if( l == 0 ) 70 { 71 // apply Canny. Take the upper threshold from slider 72 // and set the lower to 0 (which forces edges merging) 73 Canny(gray0, gray, 0, thresh, 5); 74 // dilate canny output to remove potential 75 // holes between edge segments 76 dilate(gray, gray, Mat(), Point(-1,-1)); 77 } 78 else 79 { 80 // apply threshold if l!=0: 81 // tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0 82 gray = gray0 >= (l+1)*255/N; 83 } 84 85 // find contours and store them all as a list 86 findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); 87 88 vector<Point> approx; 89 90 // test each contour 91 for( size_t i = 0; i < contours.size(); i++ ) 92 { 93 // approximate contour with accuracy proportional 94 // to the contour perimeter 95 approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); 96 97 // square contours should have 4 vertices after approximation 98 // relatively large area (to filter out noisy contours) 99 // and be convex. 100 // Note: absolute value of an area is used because 101 // area may be positive or negative - in accordance with the 102 // contour orientation 103 if( approx.size() == 4 && 104 fabs(contourArea(Mat(approx))) > 1000 && 105 isContourConvex(Mat(approx)) ) 106 { 107 double maxCosine = 0; 108 109 for( int j = 2; j < 5; j++ ) 110 { 111 // find the maximum cosine of the angle between joint edges 112 double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1])); 113 maxCosine = MAX(maxCosine, cosine); 114 } 115 116 // if cosines of all angles are small 117 // (all angles are ~90 degree) then write quandrange 118 // vertices to resultant sequence 119 if( maxCosine < 0.3 ) 120 squares.push_back(approx); 121 } 122 } 123 } 124 } 125 } 126 127 128 // the function draws all the squares in the image 129 static void drawSquares( Mat& image, const vector<vector<Point> >& squares ) 130 { 131 for( size_t i = 0; i < squares.size(); i++ ) 132 { 133 const Point* p = &squares[i][0]; 134 int n = (int)squares[i].size(); 135 polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA); 136 } 137 138 imshow(wndname, image); 139 } 140 141 int main(){ 142 143 144 string msg="press q , Q or ESC to close this program"; 145 cout << msg << endl; 146 VideoCapture capture(0); 147 if(!capture.isOpened()) return 1; 148 Mat image; //frame of video 149 string window_name="Extracted Frame"; 150 namedWindow(window_name); 151 while(true){ 152 capture >> image; 153 vector<vector<Point> > squares; 154 if(image.data){ 155 findSquares(image, squares); 156 drawSquares(image, squares); 157 } 158 if(waitKey(30)>=0) break; 159 } 160 161 return 0; 162 }
Greatness is never a given, it must be earned.