2016-12-07 5 views
2

Ich bin neu in JavaCV. Ich versuche, das größte Rechteck im Bild zu erkennen und es mit der Farbe über dem Originalbild zu umreißen. Ich poste Code, unter dem ich versucht habe, aber es funktioniert nicht. Ich bekomme edgeDetectedImage richtig. Ich bekomme 4 Eckpunkte richtig. Nur cvDrawLine funktioniert nicht. Bitte helfen, wenn ich nichts vermisse:Android: Shape-Erkennung mit JavaCV

der Schaltfläche Ich verarbeite Bild und zeige es wieder auf ImageView. In onClickListener der Taste:

if ((new File(path + "trial.jpg")).exists()) { 
    opencv_core.IplImage originalImage = opencv_imgcodecs.cvLoadImage(path + "trial.jpg", opencv_imgcodecs.CV_IMWRITE_JPEG_QUALITY); 
    opencv_core.IplImage iplImage = opencv_imgcodecs.cvLoadImage(path + "trial.jpg", opencv_imgcodecs.CV_LOAD_IMAGE_GRAYSCALE); 
    opencv_core.IplImage edgeDetectedImage = applyCannyRectangleEdgeDetection(iplImage, 80); 
    opencv_core.CvSeq largestContour = findLargestContour(edgeDetectedImage); 
    opencv_core.CvPoint[] cvPoints = new opencv_core.CvPoint[4]; 
    for(int i=0; i<largestContour.total();i++) 
    { 
    opencv_core.CvPoint cvPoint = new opencv_core.CvPoint(cvGetSeqElem(largestContour, i)); 
    cvPoints[i] = cvPoint; 
    } 
    cvDrawLine(originalImage, cvPoints[0], cvPoints[1], opencv_core.CvScalar.YELLOW, 10, 10, 10); 
    cvDrawLine(originalImage, cvPoints[1], cvPoints[2], opencv_core.CvScalar.YELLOW, 10, 10, 10); 
    cvDrawLine(originalImage, cvPoints[2], cvPoints[3], opencv_core.CvScalar.YELLOW, 10,10, 10); 
    cvDrawLine(originalImage, cvPoints[3], cvPoints[0], opencv_core.CvScalar.YELLOW, 10, 10,10); 
    opencv_imgcodecs.cvSaveImage(path + "img1.jpg", originalImage); 
        if ((new File(path + "img1.jpg").exists())) { 
         imageView.setImageDrawable(Drawable.createFromPath(path + "img1.jpg")); 
        } 
       } 

Method applyCannyRectangleEdgeDetection (IplImage, int):

private opencv_core.IplImage applyCannyRectangleEdgeDetection(opencv_core.IplImage iplImage, int percent) { 
    opencv_core.IplImage destImage = downScaleImage(iplImage, percent); 
    OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat(); 
    Frame grayImageFrame = converterToMat.convert(destImage); 
    opencv_core.Mat grayImageMat = converterToMat.convertToMat(grayImageFrame); 
    GaussianBlur(grayImageMat, grayImageMat, new opencv_core.Size(5, 5), 0.0, 0.0, BORDER_DEFAULT); 
    destImage = converterToMat.convertToIplImage(grayImageFrame); 
    cvErode(destImage, destImage); 
    cvDilate(destImage, destImage); 
    cvCanny(destImage, destImage, 20, 55); 
    return destImage; 
} 

Method downScaleImage (IplImage, int)

private opencv_core.IplImage downScaleImage(opencv_core.IplImage srcImage, int percent) { 
    opencv_core.IplImage destImage = cvCreateImage(cvSize((srcImage.width() * percent)/100, (srcImage.height() * percent)/100), srcImage.depth(), srcImage.nChannels()); 
    cvResize(srcImage, destImage); 
    return destImage; 
} 

Method findLargestContour (IplImage)

private opencv_core.CvSeq findLargestContour(opencv_core.IplImage edgeDetectedImage) { 
    opencv_core.IplImage foundContoursOfImage = cvCloneImage(edgeDetectedImage); 
    opencv_core.CvMemStorage memory = new opencv_core.CvMemStorage().create(); 
    opencv_core.CvSeq contours = new opencv_core.CvSeq(); 
    cvFindContours(foundContoursOfImage, memory, contours, Loader.sizeof(opencv_core.CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, new opencv_core.CvPoint(0, 0)); 
    int maxWidth = 0; 
    int maxHeight = 0; 
    opencv_core.CvRect contr = null; 
    opencv_core.CvSeq seqFound = null; 
    opencv_core.CvSeq nextSeq; 
    for (nextSeq = contours; nextSeq != null; nextSeq = nextSeq.h_next()) { 
     contr = cvBoundingRect(nextSeq, 0); 
     if ((contr.width() >= maxWidth) && (contr.height() >= maxHeight)) { 
      maxHeight = contr.height(); 
      maxWidth = contr.width(); 
      seqFound = nextSeq; 
     } 
    } 
    opencv_core.CvSeq result = cvApproxPoly(seqFound, Loader.sizeof(opencv_core.CvContour.class), memory, CV_POLY_APPROX_DP, cvContourPerimeter(seqFound) * 0.1, 0); 
    return result; 
} 

Antwort

0

Sorry das sollte in Kommentaren sein, aber ich habe nicht genug Ruf. Was ich aus Ihrem Code ersehen kann, ist, dass das Schlaue auf ein verkleinertes Bild angewendet wird und auch die Kontur. Sie zeichnen die Linien auf dem Originalbild (das nicht um Prozent verkleinert ist), also würde es natürlich nicht korrekt aussehen (wenn es nicht korrekt aussieht, aber etwas gezeichnet wird). Ansonsten sollten Sie den Farbraum des Bildes erwähnen, es ist nicht wichtig für die Zeichnung, aber für canny.

+0

Ich nehme Punkte von herunterskalierten Bild und Zeichnung auf Bild. All diese Operationen wurden durchgeführt, um diese 4 Eckpunkte zu erhalten. Und mit diesen Punkten zeichne ich Linien auf das Originalbild. Was Sie dazu sagen, obwohl die Dimensionen auf dem Originalbild nicht korrekt sind, aber zumindest etwas auf das Bild gezeichnet werden sollte. In meinem Fall hier ist nichts auf das Bild gezeichnet. –

+0

Können Sie das Bild und die Eckpunkte posten? Wenn nicht, haben Sie die Koordinaten der Ecken des Rechtecks ​​mit dem Bild verifiziert? –

+0

Da aus Ihrem Code sieht es so aus, als ob die Konturen aus einem Bild extrahiert werden, das 0,8 der Größe des Originalbildes entspricht, auf das Sie zeichnen. Welche Version von OpenCV benutzt du? –

Verwandte Themen