org bytedeco java opencv javacv

bytedeco - ¿Por qué el método cvFindContours() no detecta contornos correctamente en javacv?



opencv download java (1)

Realicé muchas preguntas en StackOverflow y pude desarrollar un pequeño programa para detectar cuadrados y rectángulos correctamente. Este es mi código de muestra

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(), src.height()); tgray = cvCreateImage(sz, src.depth(), 1); gray = cvCreateImage(sz, src.depth(), 1); // cvCvtColor(gray, src, 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()) < 50000) { System.out.println("Width : " + x.width() + " Height : " + x.height()); cvSeqPush(squares, approx); } } } } contours = contours.h_next(); } contours = new CvContour(); } } return squares; }

Uso esta imagen para detectar rectángulos y cuadrados

Necesito identificar la siguiente salida

y

Pero cuando ejecuto el código anterior, solo detecta los siguientes rectángulos. Pero no sé el motivo para eso. Por favor alguien puede explicar la razón por eso.

Este es el resultado que obtuve.

Tenga la amabilidad de explicar el problema en el código anterior y sugiera algunas sugerencias para detectar estos cuadrados y rectángulos.