How to identify polygon using opencv or javacv?

c++, java, javacv, opencv

Solution

I found solution to your problem:

- Convert image to grayscale:

- Do a threshold (convert to 1bit image):

- Find contours and fill them:

Hint: to fill contours in OpenCV use `-1` as `thickness` parameter in `drawContours` function.

- Do a dilatation and after this erosion with the same kernel:

And that's it! After this it is not a problem for you to find your T-shaped figure on the image!

Unfortunatelly I don't know JavaCV but I can share with you c++ code:

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.

Problem

I'm doing a project that use image processing techniques to identify different objects and their lengths. I go through many examples in javaCV as well as OpenCV. But unfortunately I was unable to identify T shape of polygon. I try to use following rectangle identification method but I failed 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 can some help me to modify this method to identify T shapes from a image. The input image is like this. This is the T shape that I have to identify

Original source