I'm using OpenCV 2.4.9 on VisualStudio V10.0.30319.1 RTMRel trying to compile this sample code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
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
VideoCapture capture;
capture.open(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH,1280);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,960);
char qq=0;
while(qq!=32)
{
qq = waitKey(30);
capture.read(src);
if(!src.empty())
imshow("Space",src);
}
/// Convert image to gray and blur it
cvtColor( src, src_gray, CV_BGR2GRAY );
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( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
/** #function thresh_callback */
void thresh_callback(int, void* )
{
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
/// Find contours
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
}
It's a sample code and should work just find but when I try to run the code just after pressing Space to capture the image the program just crashes and says "Ashkan.exe has stopped working" without any error at all!
I know the problem is with the FindContours line because as i comment that line the program runs just fine.
In debug mode when passing findContours line it says: Unhandled exception at 0x76f2320e in Ashkan.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
Does anyone know any possible cause for this problem?!
Related
I'm trying to detect and extract playing cards from an image. The plan is to detect the contours of the cards and then extract them using the area of the contours. (Is there a more efficient way of doing it?)
The problem is that I was having trouble with non-closed contours:
With this contours I'm not able to calculate the area of the rectangles. Hence, I performed morphological transformations to close the contours, producing this:
And after edge extracting:
Leaving me with these "rectangles" with twisted corners in the edges. How can I approximate these pseudo-rectangles to perfect geometric rectangles?
Is there a more efficient way of doing this?
Here is my code so far:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
#define BKG_THRESH 60 // preProcessImg
Mat src;
void preProcessImg(Mat* _img){
Mat aux_gray;
cvtColor(*_img, aux_gray, CV_BGR2GRAY );
GaussianBlur(aux_gray, *_img, Size(5,5), 0);
}
int main( int argc, char** argv ){
vector<vector<Point>> contours;
/// Load an image
src = imread("img.jpg");
preProcessImg(&src);
Canny(src, src, 30, 200);
//Mostrar imagem
namedWindow( "canny_output", CV_WINDOW_NORMAL); // Create a window
imshow( "canny_output", src);
waitKey(0);
Mat structuringElement = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
morphologyEx(src, src, MORPH_CLOSE, structuringElement);
//Mostrar imagem
namedWindow( "morph_transf", CV_WINDOW_NORMAL); // Create a window
imshow( "morph_transf", src);
waitKey(0);
findContours(src, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++){
Scalar color( rand()&255, rand()&255, rand()&255 );
drawContours( drawing, contours, i, color );
}
//Mostrar imagem
namedWindow( "contours", CV_WINDOW_NORMAL); // Create a window
imshow( "contours", drawing);
waitKey(0);
return 0;
}
The more robust way is to find lines (Hough lines) afer Canny, intersect they and find rectangles. Contours are not robust for noise.
I'm just now starting to learn how to use the openCV libraries. I've downloaded and installed openCV 2.4.10 , and have run an example " in tutorial of Finding contours in your image " using visual studio 2010. The code compiles, but every time I run it, it crashes,and I get the showing error in this image link which is as the following message:
Windows has triggered a breakpoint in EdgeDetection.exe.
This may be due to a corruption of the heap, which indicates a bug in >EdgeDetection.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while EdgeDetection.exe has focus.
The output window may have more diagnostic information.
I don't know, what is the reason.Here's the offending code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
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 );
src=cvLoadImage("fish.bmp");
/// Convert image to gray and blur it
cvtColor( src, src_gray, CV_BGR2GRAY );
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( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
/** #function thresh_callback */
void thresh_callback(int, void* )
{
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
/// Find contours
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
}
the breaking appears at line :
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
So,I would like you to help me.
Extracting different size rectangles from image using opencv does not work correctly
It doesn't give us patches of all character, just give one patch, but I want patches of all characters
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
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( "1a.bmp" );
/// Convert image to gray and blur it
cvtColor( src, src_gray, CV_BGR2GRAY );
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( (Mat)contours_poly[i], center[i], radius[i] );
}
/// Draw polygonal contour + bonding rects + circles
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
//circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
for(int i = 0; i < boundRect.size(); i++)
{
Mat patch = src(boundRect[i]);
//Do whatever you want with the patch (imshow, imwrite,...)
imshow("Patch",patch);
}
}
I think you don't have to extract the rectangles, because you already have them in your vector<Rect> boundRect.
If you want to get patches of the image that contain the rectangles/characters, you just need to cut them out:
stringstream ss;
for(int i = 0; i < boundRect.size(); i++)
{
ss>>"Patch ">>i;
Mat patch = src(boundRect[i]);
//Do whatever you want with the patch (imshow, imwrite,...)
imshow(ss.str(), patch);
ss.str("");
}
#user, you can also try this in opencv documentation
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contours = 0;
cvFindContours( img, storage, &contours, sizeof(CvContour),
CV_RETR_LIST , CV_CHAIN_APPROX_NONE, cvPoint(0,0) );
for( CvSeq* c=contours; c!=NULL; c=c->h_next)
{
CvRect Rects = cvBoundingRect( c );
}
#dennis i also need to extract line. guide me also
I am newbie in programming, so please help me. I want to retrieve only the outer contour of an object but the problem is I got another contour like a border. How can I get the only outer contour of object without any other contour?
An example image:
Here is the code I made:
// cvAutoHeight.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "opencv\cvaux.h"
#include "opencv\cxmisc.h"
#include "opencv\highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdlib.h>
using namespace std;
using namespace cv;
int main(int, char**)
{
Mat threshold_output;
int thresh = 100;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
RNG rng(12345);
CvCapture* capture = cvCaptureFromCAM(0);
cv::Mat frame; cv::Mat src_gray;
while(1) {
frame = cvQueryFrame( capture );
cvtColor( frame,src_gray, CV_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
//Canny( src_gray, threshold_output, 128, 255, 3 );
threshold( src_gray, threshold_output, 100, 200, THRESH_BINARY );
findContours( threshold_output, contours, hierarchy,CV_RETR_TREE,
CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Find the rotated rectangles and ellipses for each contour
vector<RotatedRect> minRect( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
minRect[i] = minAreaRect( Mat(contours[i]) );
}
/// Draw contours + rotated rects + ellipses
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0,0), rng.uniform(0,0), rng.uniform(250,250) );
// contour
drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0,
Point() );
// rotated rectangle
Point2f rect_points[4]; minRect[i].points( rect_points );
for( int j = 0; j < 4; j++ )
line( frame, rect_points[j], rect_points[(j+1)%4], color, 1, 8 );
}
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", frame );
cvWaitKey(33);
}
return 0;
}
`
by default, out of borders have 0 pixel value = black. after threshold, you get your black blob with white background. this why you have 2 contours. choose one of the solutions:
use binary threshold inverted.
apply canny after threshold.
I want to find the centroid of each contour.for that i take some sample code and test it..i have a prob with this coding.i got an error...Please help me to resolve that...this very useful for me...Thanks in advance...I use windows platform with visual studio 2008
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
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
IplImage* src = cvLoadImage( "TEST2.jpg");
/// Convert image to gray and blur it
cvtColor( src, src_gray, CV_BGR2GRAY );
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( "Canny thresh:","Source", &thresh, max_thresh, thresh_callback );
thresh_callback(0,0);
waitKey(0);
return(0);
}
/** #function thresh_callback */
void thresh_callback(int, void* )
{
Mat canny_output;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny( src_gray, canny_output, thresh,thresh*2,3);
/// Find contours
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Get the moments
vector<Moments> mu(contours.size());
for( int i = 0; i < contours.size(); i++ )
{
mu[i] = moments( contours[i], false );
}
/// Get the mass centers:
vector<Point2f> mc( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
}
/// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
circle( drawing, mc[i], 4, color, -1, 8, 0 );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
/// Calculate the area with the moments 00 and compare with the result of the OpenCV function
printf("\t Info: Area and Contour Length \n");
for( int i = 0; i< contours.size(); i++ )
{
printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
circle( drawing, mc[i], 4, color, -1, 8, 0 );
}
}
The error lik...
Error 2 error C2664: 'cv::moments' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const cv::Mat &' d:\aranga_try\new_opencv\new_opencv\auto_focustest.cpp 57 New_opencv
Error 8 error C2664: 'cv::contourArea' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const cv::Mat &' d:\aranga_try\new_opencv\new_opencv\auto_focustest.cpp 84 New_opencv
Error 9 error C2664: 'cv::arcLength' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const cv::Mat &' d:\aranga_try\new_opencv\new_opencv\auto_focustest.cpp 84 New_opencv
You need to explicitly convert std::vector<cv::Point> to cv::Mat by calling
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
After getting the matrix, you can compute moments, area or perimeter. For example, to compute area:
double area = cv::contourArea(cv::Mat(contours[i], false));