I would like to find the pixel coordinates of the 4 corner points of the detected rectangle (its a airplane window that I assume is rectangle). Im able to detect the window (the rectangle) as shown in the image but then do not know how to get the pixel coordinates of the 4 rectangle corner points. I think they can be detected by harris corner , right? Then can store coordinates of corner points in matrix S?
here the code
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<dirent.h>
#include<string.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 5;
int max_thresh = 60000;
RNG rng(12345);
const char* source_window = "Source image";
const char* corners_window = "Corners detected";
//int thresh = 1;
//int max_thresh = 300;
//void thresh_callback(int, void* );
static 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);
}
void setLabel(cv::Mat& im, const std::string label, std::vector<cv::Point>& contour)
{
int fontface = cv::FONT_HERSHEY_SIMPLEX;
double scale = 0.4;
int thickness = 1;
int baseline = 0;
cv::Size text = cv::getTextSize(label, fontface, scale, thickness, &baseline);
cv::Rect r = cv::boundingRect(contour);
cv::Point pt(r.x + ((r.width - text.width) / 2), r.y + ((r.height + text.height) / 2));
cv::rectangle(im, pt + cv::Point(0, baseline), pt + cv::Point(text.width, -text.height), CV_RGB(255,255,255), CV_FILLED);
cv::putText(im, label, pt, fontface, scale, CV_RGB(0,0,0), thickness, 8);
}
int main(int argc,char** argv)
{
IplImage *desimg,*srcimg;
string dirName = "C:/B787/" "/";
DIR *dir;
dir = opendir(dirName.c_str());
string imgName;
struct dirent *ent;
if (dir != NULL) {
while ((ent = readdir (dir)) != NULL) {
imgName= ent->d_name;
if(imgName.compare(".")!= 0 && imgName.compare("..")!= 0)
{
string aux;
aux.append(dirName);
aux.append(imgName);
cout << aux << endl;
Mat image= imread(aux);
//imshow(aux,image);
waitKey(0);
//resize(image, image, Size(640,480), 0, 0, INTER_CUBIC);
//char* source_window = "Source";
//namedWindow( source_window, CV_WINDOW_AUTOSIZE );
//imshow( source_window, image );
//================================
Mat gray,bw,dil,erd, dst_final;
//cv::GaussianBlur(image, src_gray, cv::Size(9, 9), 2, 2); //original
//cv::GaussianBlur(image, src_gray, cv::Size(3,3), 1,1,BORDER_DEFAULT); //original
cv::GaussianBlur(image, src_gray, cv::Size(3,3),1,1,BORDER_DEFAULT); //original
medianBlur(image, src_gray, 11);
blur( image, src_gray, Size(3,3) );
cvtColor(src_gray,gray,CV_BGR2GRAY);
//cvtColor( src, src_gray, COLOR_BGR2HSV );
//blur( src_gray, gray, Size(1,3) );
//medianBlur(src, src_gray,, 5);
Canny(gray,bw,600,1200,5,true);
//Canny(gray,bw,1200,600,5,true);
//Canny(gray,bw,thresh, thresh*1, 5,true);
//Canny( src_gray, canny_output, thresh, thresh*1, 3 );
//dilate(bw,dil,Mat());
//erode(dil,erd,Mat());
//Mat tmp=bw.clone();
//cvtColor( src, src_gray, COLOR_BGR2GRAY);
//blur( src_gray, src_gray, Size(1,3) );
// medianBlur(src_gray, src_gray, 3);
//cv::GaussianBlur(src_gray, src_gray, cv::Size(9, 9), 2, 2);
/////////Mat gray;
/////////cvtColor(src, gray, CV_BGR2GRAY);
////////Mat bw;
//compute mask (you could use a simple threshold if the image is always as good as the one you provided)
//cv::Mat mask;
//cv::threshold(src_gray, mask, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);
//Canny(gray, bw, 800, 850, 5, true);
//imshow("canny", bw);
//Size kernalSize (22,59);
//Size kernalSize (22,54);
//Mat element = getStructuringElement (MORPH_CROSS, kernalSize, Point(1,25) );
//Mat element = getStructuringElement (MORPH_RECT, kernalSize, Point(1,21) );
//morphologyEx( bw, bw, MORPH_CLOSE, element );
Mat grad,bw1;
Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(36, 29));
// Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(8, 3));
morphologyEx(bw, grad, MORPH_GRADIENT, morphKernel);
// binarize
//Mat bw;
threshold(grad, bw1, 255.0, 255.0, THRESH_BINARY | THRESH_OTSU);
// connect horizontally oriented regions
Mat connected;
morphKernel = getStructuringElement(MORPH_RECT, Size(31, 24));
//morphKernel = getStructuringElement(MORPH_RECT, Size(5, 1));
morphologyEx(bw1, connected, MORPH_CLOSE, morphKernel);
// find contours
Mat mask = Mat::zeros(bw.size(), CV_8UC1);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;//novo
findContours(connected.clone(), contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
//findContours(bw.clone(), contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
//findContours(connected.clone(), contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(1,1));
//findContours(connected, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE,Point(0,0));
//findContours(connected, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(1,1));
//findContours(connected, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(1,1));
//findContours(connected, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
//findContours(bw.clone(), contours,hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
vector<Point> approx;
Mat dst = image.clone();
// for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
//{
// Rect rect = boundingRect(contours[idx]);
// if (rect.height > 8 && rect.width > 9 && rect.height < 60 && rect.width < 60) /* constraints on region size */
for( int i = 0; i< contours.size(); i++ )
{
//approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.071, true);
//approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.041, true);
//approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.031, true);
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.061, true);
if (approx.size() >= 4 && approx.size() <= 6)
{
int vtc = approx.size();
vector<double> cos;
for(int j = 2; j < vtc + 1; j++)
cos.push_back(angle(approx[j%vtc], approx[j-2], approx[j-1]));
sort(cos.begin(), cos.end());
double mincos = cos.front();
double maxcos = cos.back();
if (vtc >=3 && vtc <6 /*&& mincos >= -0.2 && maxcos <= 0.5*/)
{
Rect r = boundingRect(contours[i]);
double ratio = abs(1 - (double)r.width / r.height);
if (r.height >15 && r.width >10 && r.height < 600 && r.width < 600 && r.height>r.width && (r.height/r.width)>1.5 /*&& (r.height/r.width)<2.05 */ ) /* constraints on region size */
{
//Rect r = boundingRect(contours[i]);
//double ratio = abs(1 - (double)r.width / r.height);
line(dst, approx.at(0), approx.at(1), cvScalar(0,0,255),4);
line(dst, approx.at(1), approx.at(2), cvScalar(0,0,255),4);
line(dst, approx.at(2), approx.at(3), cvScalar(0,0,255),4);
line(dst, approx.at(3), approx.at(0), cvScalar(0,0,255),4);
}
}
}
}
//================================
//Here detecting the 4 corner points and save to marix S
Mat S(0, 2, CV_32SC1);
cvtColor( image, src_gray, CV_BGR2GRAY );
Mat dst1, dst_norm,dst_norm_scaled;
dst1 = Mat::zeros( src.size(), CV_32FC1 );
int blockSize = 2;
int apertureSize = 3;
double k = 0.04;
/// Detecting corners
//cornerHarris( src_gray, dst1, blockSize, apertureSize, k, BORDER_DEFAULT );
/// Normalizing
//normalize( dst1, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
//convertScaleAbs( dst_norm, dst_norm_scaled );
/// Drawing a circle around corners
// for( int j = 0; j < dst_norm.rows ; j++ )
// { for( int i = 0; i < dst_norm.cols; i++ )
// {
// if( (int) dst_norm.at<float>(j,i) > thresh )
// {
// circle( dst_norm, Point( i, j ), 5, Scalar(0), 2, 8, 0 );
// Mat pt(1,2,CV_32SC1);
// pt.at<int>(0, 0) = i;
// pt.at<int>(0, 1) = j;
// Add the point to S
//S.push_back(pt);
// }
// }
// }
// namedWindow( corners_window, WINDOW_AUTOSIZE );
// imshow( corners_window, dst_norm_scaled );
resize(image, image, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window4 = "Detected window on the input image";
namedWindow( source_window4, CV_WINDOW_AUTOSIZE );
imshow( source_window4, dst );
}
}
closedir (dir);
} else {
cout<<"not present"<<endl;
}
return 0;
}
Any help?
Here the detected windows( quasi rectangles)