Created
September 12, 2012 22:46
-
-
Save WPsites/3710541 to your computer and use it in GitHub Desktop.
Find contours in an image and output x,y data structure of all found contours (OpenCV)
This file contains hidden or 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
| #!/bin/sh | |
| i="shape-detect.cpp" | |
| echo "compiling $i" | |
| g++ -ggdb `pkg-config --cflags opencv` -o `basename $i .cpp` $i `pkg-config --libs opencv`; |
This file contains hidden or 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
| /* | |
| Usage: ./shape-detect.cpp image-name-with-shapes-in.jpg | |
| Feed in an image to process and two windows will display, one with the image to be process with a slider to adjust threshold | |
| and another window to display the results. | |
| A JSON like data structure of id,x,y data for each shape detected will be output to the command line. | |
| Each adjustment of the threshold will output a new data structure. | |
| This file is set to draw small circles but the code is there to draw a polygonal contour or bonding rectangles. | |
| You will need the OpenCV library to use this. | |
| A build script is also included here. | |
| */ | |
| #include "opencv2/highgui/highgui.hpp" | |
| #include "opencv2/imgproc/imgproc.hpp" | |
| #include <iostream> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <fstream> | |
| using namespace cv; | |
| using namespace std; | |
| Mat src; Mat src_gray; | |
| int thresh = 100; | |
| int max_thresh = 255; | |
| RNG rng(12345); | |
| /// Function header | |
| void thresh_callback(int, void* ); | |
| /** @function main */ | |
| int main( int argc, char** argv ) | |
| { | |
| /// Load source image and convert it to gray | |
| src = imread( argv[1], 1 ); | |
| /// Convert image to gray and blur it | |
| cvtColor( src, src_gray, CV_BGR2GRAY ); | |
| /// adding a blur can sometimes improve results on otherwise noisy images | |
| /// blur( src_gray, src_gray, Size(3,3) ); | |
| /// Create Window | |
| char* source_window = "Source"; | |
| namedWindow( source_window, CV_WINDOW_AUTOSIZE ); | |
| imshow( source_window, src ); | |
| createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback ); | |
| thresh_callback( 0, 0 ); | |
| waitKey(0); | |
| return(0); | |
| } | |
| /** @function thresh_callback */ | |
| void thresh_callback(int, void* ) | |
| { | |
| Mat threshold_output; | |
| vector<vector<Point> > contours; | |
| vector<Vec4i> hierarchy; | |
| /// Detect edges using Threshold | |
| threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY ); | |
| /// Find contours | |
| 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() ); | |
| for( int i = 0; i < contours.size(); i++ ) | |
| { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); | |
| boundRect[i] = boundingRect( Mat(contours_poly[i]) ); | |
| minEnclosingCircle( contours_poly[i], center[i], radius[i] ); | |
| } | |
| /// Draw polygonal contour, bonding rects or circles | |
| Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); | |
| for( int i = 0; i< contours.size(); i++ ) | |
| { | |
| // use a random color: Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); | |
| Scalar color = Scalar( 0, 0, 240 ); | |
| // draw contours: drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() ); | |
| // draw rectangle: rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); | |
| // draw circle with dynamic radious: circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 ); | |
| circle( drawing, center[i], 2, color, 2, 8, 0 ); | |
| /// print data sctructure to command line to be used in another program etc | |
| cout << "{id:" << i << ",x:" << center[i].x << ",y:" << center[i].y << "}," << flush; | |
| } | |
| /// print some clear lines to command line to seperate output from different runs | |
| cout << "\n \n" << flush; | |
| /// Show in a window | |
| namedWindow( "Contours", CV_WINDOW_AUTOSIZE ); | |
| imshow( "Contours", drawing ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm using OpenCV4Tegra and Linux, Jetson TK1 board.
I met this error 👍
ubuntu@tegra-ubuntu:
/FindBiggestBlobWithGithubContours/build$ ./'ZED with OpenCV'/FindBiggestBlobWithGithubContours/build$ ./'ZED with OpenCV'terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Aborted
ubuntu@tegra-ubuntu:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Aborted