How to define a polygon using opencv or javacv?

I am doing a project that uses image processing methods to identify different objects and their length. I am looking at a lot of examples in javaCV as well as OpenCV. But, unfortunately, I could not determine the T-image of the polygon.

I am trying to use the following rectangle identification method, but I could not execute it.

public static CvSeq findSquares( final IplImage src, CvMemStorage storage) { CvSeq squares = new CvContour(); squares = cvCreateSeq(0, sizeof(CvContour.class), sizeof(CvSeq.class), storage); IplImage pyr = null, timg = null, gray = null, tgray; timg = cvCloneImage(src); CvSize sz = cvSize(src.width() & -2, src.height() & -2); tgray = cvCreateImage(sz, src.depth(), 1); gray = cvCreateImage(sz, src.depth(), 1); pyr = cvCreateImage(cvSize(sz.width()/2, sz.height()/2), src.depth(), src.nChannels()); // down-scale and upscale the image to filter out the noise cvPyrDown(timg, pyr, CV_GAUSSIAN_5x5); cvPyrUp(pyr, timg, CV_GAUSSIAN_5x5); cvSaveImage("ha.jpg", timg); CvSeq contours = new CvContour(); // request closing of the application when the image window is closed // show image on window // find squares in every color plane of the image for( int c = 0; c < 3; c++ ) { IplImage channels[] = {cvCreateImage(sz, 8, 1), cvCreateImage(sz, 8, 1), cvCreateImage(sz, 8, 1)}; channels[c] = cvCreateImage(sz, 8, 1); if(src.nChannels() > 1){ cvSplit(timg, channels[0], channels[1], channels[2], null); }else{ tgray = cvCloneImage(timg); } tgray = channels[c]; // try several threshold levels for( int l = 0; l < N; l++ ) { // hack: use Canny instead of zero threshold level. // Canny helps to catch squares with gradient shading if( l == 0 ) { // apply Canny. Take the upper threshold from slider // and set the lower to 0 (which forces edges merging) cvCanny(tgray, gray, 0, thresh, 5); // dilate canny output to remove potential // // holes between edge segments cvDilate(gray, gray, null, 1); } else { // apply threshold if l!=0: cvThreshold(tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY); } // find contours and store them all as a list cvFindContours(gray, storage, contours, sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); CvSeq approx; // test each contour while (contours != null && !contours.isNull()) { if (contours.elem_size() > 0) { approx = cvApproxPoly(contours, Loader.sizeof(CvContour.class),storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0); if( approx.total() == 4 && Math.abs(cvContourArea(approx, CV_WHOLE_SEQ, 0)) > 1000 && cvCheckContourConvexity(approx) != 0 ){ double maxCosine = 0; // for( int j = 2; j < 5; j++ ) { // find the maximum cosine of the angle between joint edges double cosine = Math.abs(angle(new CvPoint(cvGetSeqElem(approx, j%4)), new CvPoint(cvGetSeqElem(approx, j-2)), new CvPoint(cvGetSeqElem(approx, j-1)))); maxCosine = Math.max(maxCosine, cosine); } if( maxCosine < 0.2 ){ CvRect x=cvBoundingRect(approx, l); if((x.width()*x.height())<5000 ){ System.out.println("Width : "+x.width()+" Height : "+x.height()); cvSeqPush(squares, approx); //System.out.println(x); } } } } contours = contours.h_next(); } contours = new CvContour(); } } return squares; } 

Please help me modify this method to determine the T-shapes from the image. The input image is as follows.

enter image description here

This is the T form that I have to identify.

enter image description here

+8
java c ++ opencv javacv
source share
3 answers

I found a solution to your problem:

  • Convert image to grayscale:

grayscale image

  • Make a threshold value (conversion to 1-bit image):

2bit image

  • Find the contours and fill them out:

filled image

Hint: to fill outlines in OpenCV, use -1 as the thickness parameter in drawContours .

  • Make an extension after this erosion with the same core:

result image

And this! After that, it will not be difficult for you to find the figure T in the image!

Unfortunately, I do not know JavaCV , but I can share C ++ code with you:

 Mat src = imread("in.jpg"), gray; cvtColor(src, gray, CV_BGR2GRAY); threshold(gray, gray, 230, 255, THRESH_BINARY_INV); vector<Vec4i> hierarchy; vector<vector<Point> > contours; findContours(gray, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); gray = Scalar::all(255); for (size_t i=0; i<contours.size(); i++) { drawContours(gray, contours, i, Scalar(0), -1); } Mat element = getStructuringElement(MORPH_RECT, Size(2, 2), Point(1, 1)); dilate(gray, gray, element); erode(gray, gray, element); imshow("window", gray); 

Hint: if you want, you can convert this code to JavaCV. To do this, read this tutorial .

+6
source share

Perhaps you better find the paths and use CvApproxPoly() . You can find a good example of how to use this function to search for rectangles here and adapt them to search for your T-shapes. This example is created using OpenCV and written in C ++.

Go through all the points in the sequence:

 for (int i = 0; i < cornerPoints->total; i++) { CvPoint *cornerPoints = (CvPoint*) cvGetSeqElem(cornerPoints, i); } 
+1
source share

sounds like homework though

@Astor preprocessing is definitely useful. but I still think that this shape recognition is closely related to image processing: morphology

Could you prepare a T-shape template and then curl up? template with pre-processed result. I canโ€™t remember more details, just look at the morphology and convolution of the TAG

0
source share

All Articles