利用opencv检测出矩形1
2016-03-15 16:23
423 查看
利用opencv检测出矩形
//#include "stdafx.h" #include <opencv2/opencv.hpp> #include <iostream> #include <windows.h> using namespace cv; using namespace std; int* findRectInfo(std::vector<cv::Point> rect) { int rectInfo[4] = {0}; int x[4]= {0},y[4]= {0}; int maxX = 0,maxY = 0,minX = 2000,minY = 2000; //get the rect points for(int i=0;i<4;i++) { x[i] = rect[i].x; y[i] = rect[i].y; if(maxX<x[i]) maxX = x[i]; if(maxY<y[i]) maxY = y[i]; if(minX>x[i]) minX = x[i]; if(minY>y[i]) minY = y[i]; } rectInfo[0] = minY; rectInfo[1] = minX; rectInfo[2] = maxY - minY; rectInfo[3] = maxX - minX; cout<<"minY="<<minY<<endl; cout<<"minX="<<minX<<endl; cout<<"maxY - minY="<<maxY - minY<<endl; cout<<"maxX - minX="<<maxX - minX<<endl; return rectInfo;// 得到矩形的左上角的坐标和矩形的边长 } double angle(Point pt1, Point pt2, Point pt0) { double dx1 = pt1.x - pt0.x; double dy1 = pt1.y - pt0.y; double dx2 = pt2.x - pt0.x; double dy2 = pt2.y - pt0.y; return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); }//勾股定理验证是否满足直角的关系 int main(int argc, char* argv[]) { VideoCapture cap; cap.open(0); if (!cap.isOpened()) { return -1; } double w = 320, h = 320; cap.set(CV_CAP_PROP_FRAME_WIDTH, w); cap.set(CV_CAP_PROP_FRAME_HEIGHT, h); namedWindow("Video"); bool stop = false; Mat frame1,frame2,frame3; //IplImage* image; CvMemStorage* storage = NULL; while (!stop) { cap>> frame1; //image = &IplImage(frame); //IplImage *img1 = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); cvtColor(frame1, frame2, CV_BGR2GRAY); GaussianBlur(frame2, frame3, cv::Size(5, 5), 0, 0); //cvShowImage("AV", img1); // Quantize the gray scale to 30 levels int gbins = 16; int histSize[] = { gbins }; // gray scale varies from 0 to 256 float granges[] = { 0,256 }; const float* ranges[] = { granges }; cv::MatND hist; // we compute the histogram from the 0-th and 1-st channels int channels[] = { 0 }; //calculate hist calcHist(&frame2, 1, channels, cv::Mat(), // do not use mask hist, 1, histSize, ranges, true, // the histogram is uniform false); //find the max value of hist double maxVal = 0; minMaxLoc(hist, 0, &maxVal, 0, 0); int scale = 20; cv::Mat histImg; histImg.create(500, gbins*scale, CV_8UC3); //show gray scale of hist image for (int g = 0; g<gbins; g++) { float binVal = hist.at<float>(g, 0); int intensity = cvRound(binVal * 255); rectangle(histImg, cv::Point(g*scale, 0), cv::Point((g + 1)*scale - 1, binVal / maxVal * 400), CV_RGB(0, 0, 0), CV_FILLED); } imshow("histImg", histImg); // processing Mat hsvRe; threshold(frame3, hsvRe, 150, 255, cv::THRESH_BINARY);//阈值设定函数 形式:void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type ); vector<vector<Point>> contours; //contours指所有轮廓 vector<Vec4i> hierarchy; // find findContours(hsvRe, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);//找出图片中的所有轮廓 // draw //Mat result(hsvRe.size(), CV_8U, Scalar(0)); //drawContours(result, contours, -1, Scalar(255), 2); //namedWindow("contours"); //imshow("contours", result); imshow("Video1", frame1); imshow("Video2", frame2); imshow("Video3", hsvRe); //.......................识别矩形.................................................//. vector<Point> approx; vector<vector<Point>> squares; for (size_t i = 0; i < contours.size(); i++)//表示所有的轮廓 { approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); if (approx.size() == 4 && fabs(contourArea(Mat(approx))) > 1000 && isContourConvex(Mat(approx))) { double maxCosine = 0; for( int j = 2; j < 5; j++ ) { double cosine = fabs(angle(approx[j%4],approx[j-2], approx[j-1])); maxCosine = MAX(maxCosine, cosine); } if( maxCosine < 0.1 ) squares.push_back(approx); } } //...........................get rect from image........................................... std::vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); Mat image(3210,3210,CV_8UC3,Scalar(0)); for(int i=0;i<squares.size();i++) { int rect[4],*tmp; tmp = findRectInfo(squares[i]); cout<<i<<endl; for(int j=0;j<4;j++) { rect[j] = *(tmp+j); } cv::Rect roi(rect[1],rect[0],rect[3],rect[2]); cout<<"w:"<<roi.width<<endl; cout<<"w:"<<roi.height<<endl; //cv::Mat roi_of_image = image(roi); } /*char * filename = new char[100]; sprintf(filename,"F:\\Temp\\%i.png",i); imshow("Video4", roi_of_image); cv::imwrite(filename,roi_of_image,compression_params);*/ /* }*/ //............................... //storage = cvCreateMemStorage(0); //cvNamedWindow(wndname, 1); // find and draw the squares //cvReleaseImage(&image); //cvClearMemStorage(storage); if (waitKey(27) >= 0)//Esc键退出 stop = true; } return 0; }
这个程序是自己在网上各种查阅和拼凑在一起能检测出矩形的程序。
相关文章推荐
- Linux命令之文件系统(六)
- 在windows下编辑好Shell脚本,在Linux中运行
- 在Centos7上安装漏洞扫描软件Nessus
- linux下 fork(),vfork(),clone()的用法及区别
- CentOS 6.4安装配置LAMP服务器(Apache+PHP5+MySQL)
- PXE批量部署Linux之二:UEFI平台
- Linux 安装SNMP v3
- Linux命令之文件系统(五)
- 利用opencv检测出矩形
- Nginx反向代理80端口,实现同一台服务器多个80端口
- arm-linux移植MT7601Uusb无线网卡(小度wifi,360随身WIFI 2代)
- awbeci网站之技术篇
- 汇总Linux命令---压缩解压,查看文件夹大小
- centos6 升级libvirt qemu
- Linux命令之文件系统(四)
- opencv:问题记录,及时备忘
- ubuntu12.04下安装kcope
- 添加path linux
- elasticsearch集群监控工具bigdesk
- 关于虚拟地址,线性地址,逻辑地址还有物理地址的区分