1

J'utilise OpenCV4Android version 2.4.11 et j'essaie de détecter les rectangles dans les images extraites de la caméra. J'ai fait référence à quelques questions sur ce site et ils ont été très utiles. mais le problème que je suis actuellement est lorsque j'essaie de détecter un objet avec la couleur de la lumière au milieu comme indiqué dans l'image originale ci-dessous l'algorithme de détection dans ce cas ne détecte pas l'objet dans son ensemble, plutôt il détecte les parties sombres de comme indiqué dans l'image dans la section intitulée "traitée" ci-dessous. Le code affiché ci-dessous indique les étapes que j'ai suivies et les valeurs de seuil i utilisées pour détecter les objets dans les trames.Comment détecter un rectangle entier dans un cadre

s'il vous plaît laissez-moi savoir pourquoi l'objet dans son ensemble ne se détecté et que puis-je faire pour détecter l'objet entier non seulement les parties de celui-ci

code:

//step 1 
    this.mMatGray = new Mat(); 
    Imgproc.cvtColor(this.mMatInputFrame, this.mMatGray, Imgproc.COLOR_BGR2GRAY); 
    //step 2 
    this.mMatEdges = new Mat(); 
    Imgproc.blur(this.mMatGray, this.mMatEdges, new Size(7, 7));//7,7 
    //step 3 
    Imgproc.Canny(this.mMatEdges, this.mMatEdges, 128, 128*2, 5, true);//..,..,2,900,7,true 
    //step 4 
    dilated = new Mat(); 
    Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(3, 3)); 
    Imgproc.dilate(mMatEdges, dilated, dilateElement); 

    ArrayList<MatOfPoint> contours = new ArrayList<>(); 
    hierachy = new Mat(); 
    Imgproc.findContours(dilated, contours, hierachy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); 

    MatOfPoint2f approxCurve = new MatOfPoint2f(); 
    if (contours.size() > 0) { 
     for (int i = 0; i < contours.size(); i++) { 

      MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray()); 
      double approxDistance = Imgproc.arcLength(contour2f, true) * .02;//.02 
      Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true); 
      MatOfPoint points = new MatOfPoint(approxCurve.toArray()); 

      if (points.total() >= 4 && Imgproc.isContourConvex(points) && Math.abs(Imgproc.contourArea(points)) >= 40000 && Math.abs(Imgproc.contourArea(points)) <= 150000) { 
       Rect boundingRect = Imgproc.boundingRect(points); 
       RotatedRect minAreaRect = Imgproc.minAreaRect(contour2f); 
       Point[] rectPoints = new Point[4]; 
       minAreaRect.points(rectPoints); 
       Rect minAreaAsRect = minAreaRect.boundingRect(); 

       //to draw the minAreaRect 
       for(int j = 0; j < 4; j++) { 
        Core.line(mMatInputFrame, rectPoints[j], rectPoints[(j+1)%4], new Scalar(255,0,0)); 
       } 
       Core.putText(mMatInputFrame, "MinAreaRect", new Point(10, 30), 1,1 , new Scalar(255,0,0),2); 
       Core.putText(mMatInputFrame, "Width: " + minAreaAsRect.width , new Point(minAreaAsRect.tl().x, minAreaAsRect.tl().y-100), 1,1 , new Scalar(255,0,0),2); 
       Core.putText(mMatInputFrame, "Height: " + minAreaAsRect.height, new Point(minAreaAsRect.tl().x, minAreaAsRect.tl().y-80), 1,1 , new Scalar(255,0,0),2); 
       Core.putText(mMatInputFrame, "Area: " + minAreaAsRect.area(), new Point(minAreaAsRect.tl().x, minAreaAsRect.tl().y-60), 1,1 , new Scalar(255,0,0),2); 

       //drawing the contour 
       Imgproc.drawContours(mMatInputFrame, contours, i, new Scalar(0,0,0),2); 

       //drawing the boundingRect 
       Core.rectangle(mMatInputFrame, boundingRect.tl(), boundingRect.br(), new Scalar(0, 255, 0), 1, 1, 0); 
       Core.putText(mMatInputFrame, "BoundingRect", new Point(10, 60), 1,1 , new Scalar(0,255,0),2); 
       Core.putText(mMatInputFrame, "Width: " + boundingRect.width , new Point(boundingRect.br().x-100, boundingRect.tl().y-100), 1,1 , new Scalar(0,255,0),2); 
       Core.putText(mMatInputFrame, "Height: " + boundingRect.height, new Point(boundingRect.br().x-100, boundingRect.tl().y-80), 1,1 , new Scalar(0,255,0),2); 
       Core.putText(mMatInputFrame, "Area: " + Imgproc.contourArea(points), new Point(boundingRect.br().x-100, boundingRect.tl().y-60), 1,1 , new Scalar(0,255,0),2); 
      } 
     } 
    } 

d'origine l'image:

enter image description here

image traitée:

enter image description here

Répondre

1

nous avons mis en œuvre en C++. API sont les mêmes, donc vous pouvez facilement le port pour Android. J'ai utilisé Opencv 2.4.8. S'il vous plaît vérifier la mise en œuvre. Espérons que le code dit ce qui se fait:

#include <iostream> 
#include <string> 
#include "opencv/highgui.h" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/objdetect/objdetect.hpp" 

using namespace std; 
using namespace cv; 


Mat GetKernel(int erosion_size) 
{ 
     Mat element = getStructuringElement(cv::MORPH_CROSS, 
       cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1), 
       cv::Point(erosion_size, erosion_size)); 

     return element; 
} 
int main() 
{ 
    Mat img = imread("C:/Users/dell2/Desktop/j6B3A.png",0);//loading gray scale image 
    Mat imgC = imread("C:/Users/dell2/Desktop/j6B3A.png",1); 
    GaussianBlur(img,img,Size(7,7),1.5,1.5); 

    Mat dimg; 
    adaptiveThreshold(img,dimg,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,17,1); 



     dilate(dimg,img,GetKernel(2)); 
     erode(img,dimg,GetKernel(2)); 
     erode(dimg,img,GetKernel(1)); 


     dimg = img; 

    //* 
    vector<vector<Point>> contours; // Vector for storing contour 
    vector<Vec4i> hierarchy; 

    findContours(dimg, contours, hierarchy,CV_RETR_TREE , CV_CHAIN_APPROX_NONE); // Find the contours in the image 

    double largest_area = 0; 
    int largest_contour_index = 0; 
    Rect bounding_rect; 

    for(int i = 0; i< contours.size(); i++) // iterate through each contour. 
     { 
     double a=contourArea(contours[i],false); // Find the area of contour 
     if(a>largest_area){ 
     largest_area=a; 
     largest_contour_index=i;    //Store the index of largest contour 
     bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour 
     } 

     } 

    drawContours(imgC, contours, largest_contour_index, Scalar(255,0,0), 2, 8, hierarchy, 0, Point()); 
    rectangle(imgC, bounding_rect, Scalar(0,255,0),2, 8,0); 
/**/ 

    //imshow("display",dimg); 
    imshow("display2",imgC); 
    waitKey(0); 
    return 0; 
} 

Sortie produit:

enter image description here

Vous pouvez régler le seuil si nécessaire.

+0

merci.pouvez-vous s'il vous plaît dites-moi pourquoi avez-vous utilisé "érode puis dailate puis érode" ?? – user2121

+0

Pour construire la connectivité entre les bords déconnectés de la semaine ... –

+0

pensez-vous que si je utilisé détecteur de bord Canny je ne serais pas obtenir les mêmes résultats ?? – user2121