您的位置:首页 > 运维架构

利用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;
}


这个程序是自己在网上各种查阅和拼凑在一起能检测出矩形的程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: