Created
May 6, 2013 06:22
-
-
Save ifq/5523619 to your computer and use it in GitHub Desktop.
opencv example of branch-like sym reco.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file reco_sym.cpp | |
* @brief this is a simple try for kin san's pj, which need to reco some | |
* symbol like tree branch shape. | |
* @author ifqqfi gmail | |
* | |
*/ | |
#include "opencv2/imgproc/imgproc.hpp" | |
#include "opencv2/highgui/highgui.hpp" | |
#include <iostream> | |
#include <stdlib.h> | |
#include <stdio.h> | |
using namespace std; | |
using namespace cv; | |
/// Global variables | |
int threshold_value = 100; | |
int threshold_type = 1; | |
int const max_value = 255; | |
int const max_type = 4; | |
int const max_BINARY_value = 255; | |
RNG rng(12345); | |
Mat src, src_gray, dst; | |
const char* window_name = "Threshold Demo"; | |
const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted"; | |
const char* trackbar_value = "Value"; | |
/// Function headers | |
void Reco_Sym_Process( int, void* ); | |
/** | |
* @function main | |
*/ | |
int main( int argc, char** argv ) | |
{ | |
Mat org; | |
CvSize sz; | |
/// Load an image | |
if ( argc < 2) { | |
cout << "need a pic's filename as a param." << endl; | |
return 0; | |
} | |
org = imread( argv[1], 1 ); | |
// resize pic | |
if (org.cols > org.rows) { | |
sz.width = 800; | |
sz.height = (float)(800 / org.cols) * org.rows; | |
} else { | |
sz.width = (float)(800 / org.rows) * org.cols; | |
sz.height = 800; | |
} | |
resize(org, src, sz); | |
/// Convert the image to Gray | |
cvtColor( src, src_gray, CV_RGB2GRAY ); | |
/// Create a window to display results | |
namedWindow( window_name, CV_WINDOW_AUTOSIZE ); | |
/// Create Trackbar to choose type of Threshold | |
createTrackbar( trackbar_type, | |
window_name, &threshold_type, | |
max_type, Reco_Sym_Process ); | |
createTrackbar( trackbar_value, | |
window_name, &threshold_value, | |
max_value, Reco_Sym_Process ); | |
/// Call the function to initialize | |
Reco_Sym_Process( 0, 0 ); | |
/// Wait until user finishes program | |
for(;;) { | |
int c; | |
c = waitKey( 20 ); | |
if( (char)c == 27 ) { | |
break; | |
} | |
} | |
} | |
// check if rin is really in rout Rect | |
static inline int isRectinRect(Rect rin, Rect rout) | |
{ | |
if ((rout.x <= rin.x) && (rout.y <= rin.y) | |
&& ((rout.width + rout.x) >= (rin.width + rin.x)) | |
&& ((rout.height + rout.y) >= (rin.height + rin.y))) { | |
return 1; | |
} | |
return 0; | |
} | |
// check if r1 and r2 are a pair of frame | |
// return 1 if r1 is inner rect | |
// return 2 if r2 is inner rect | |
// return 0 if not a frame | |
static inline int framecheck(Rect r1, Rect r2 ) | |
{ | |
int a,b,c,d; | |
int avg; | |
a = abs(r1.x - r2.x); | |
b = abs(r1.y - r2.y); | |
c = abs(r1.width - r2.width); | |
d = abs(r1.height - r2.height); | |
avg = (a + b + c + d)/ 4; | |
a = abs(a - avg); | |
b = abs(b - avg); | |
c = abs(c - avg); | |
d = abs(d - avg); | |
if (a > 10 || b > 10 || c > 10 || d>10) { | |
return 0; | |
} | |
if (isRectinRect(r1, r2)) { | |
// r1 is inner | |
return 1; | |
} else if (isRectinRect(r2, r1)) { | |
// r2 is inner | |
return 2; | |
} else { | |
return 0; | |
} | |
} | |
/** | |
* @function Reco_Sym_Process | |
*/ | |
void Reco_Sym_Process( int, void* ) | |
{ | |
/* 0: Binary | |
1: Binary Inverted | |
2: Threshold Truncated | |
3: Threshold to Zero | |
4: Threshold to Zero Inverted | |
*/ | |
Mat threshold_output; | |
vector<vector<Point> > contours; | |
vector<Vec4i> hierarchy; | |
threshold( src_gray, threshold_output, threshold_value, max_BINARY_value,threshold_type ); | |
findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); | |
/// Approximate contours to polygons + get bounding rects and circles | |
vector<vector<Point> > contours_poly( contours.size() ); | |
vector<Rect> boundRect( contours.size() ); | |
vector<Point2f>center( contours.size() ); | |
vector<float>radius( contours.size() ); | |
vector<Rect> frameRect; | |
vector<Rect> symRect; | |
for( size_t i = 0; i < contours.size(); i++ ) | |
{ approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); | |
boundRect[i] = boundingRect( Mat(contours_poly[i]) ); | |
} | |
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); | |
cvtColor(threshold_output, drawing, CV_GRAY2BGR); | |
for( size_t i = 0; i< contours.size(); i++ ) | |
{ | |
// assume sym frame is at least 60% of the pic | |
if (boundRect[i].width > threshold_output.cols * 0.6 || | |
boundRect[i].height > threshold_output.rows * 0.6) { | |
frameRect.insert(frameRect.begin(), boundRect[i]); | |
} | |
} | |
// for (vector<Rect>::iterator it = frameRect.begin() ; | |
// it != frameRect.end(); it++){ | |
// Scalar color = Scalar( 255, 0, 0 ); | |
// //rectangle( drawing, it->tl(), it->br(), color, 1, 8, 0 ); | |
// } | |
// find the frame ! iwood.co.nr | |
Rect trueRect; | |
for (int x = 1; x < frameRect.size();x++) { | |
if (int ret = framecheck(frameRect[x-1], frameRect[x])) { | |
if(ret==1) { | |
trueRect = frameRect[x-1]; | |
} else { | |
trueRect = frameRect[x]; | |
} | |
cout << "rect " << x << " : " << trueRect << ", " | |
<< trueRect.size() << ", " | |
<< trueRect.area() << ", " << ret << endl; | |
Scalar color = Scalar( 0, 255, 0 ); | |
rectangle( drawing, trueRect.tl(), trueRect.br(), color, 1, 8, 0 ); | |
break; | |
} | |
} | |
// find all rect inside the frame | |
for (vector<Rect>::iterator it = boundRect.begin() ; | |
it != boundRect.end(); it++){ | |
if (isRectinRect(*it, trueRect)) { | |
symRect.insert(symRect.begin(), *it); | |
} | |
} | |
// draw all the rect inside the frame ifqqfi | |
for (vector<Rect>::iterator it = symRect.begin() ; | |
it != symRect.end(); it++){ | |
Scalar color = Scalar( 255, 0, 0 ); | |
rectangle( drawing, it->tl(), it->br(), color, 1, 8, 0 ); | |
} | |
imshow( window_name, drawing ); | |
// imshow( "src", threshold_output); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment