1

OpenCV4Androidバージョン2.4.11を使用しています。カメラから取得したフレームの四角形を検出しようとしています。私はこのウェブサイトのいくつかの質問に言及し、彼らはとても役に立ちました。私が直面している問題は、 です。この場合、検出アルゴリズムの下の元の画像に示されているように、明るい色でオブジェクトを検出しようとすると、オブジェクト全体が検出されず、暗い部分が検出されます。下の「処理済」セクションの画像に示されています。フレーム内の矩形全体を検出する方法

以下に掲載されているコードは、私が従った手順と、フレーム内のオブジェクトを検出するために使用したしきい値を示しています。

全体として物体が検出取得されていない理由を私は知っていると私は、全体の物体を検出するために何を行うことができますしてくださいではない、それの部分だけ

コード

//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); 
      } 
     } 
    } 

元画像

enter image description here

処理された画像は:

enter image description here

答えて

1

私はC++で実装しています。 APIは同じなので、簡単にアンドロイドに移植することができます。私はOpencv 2.4.8を使用しました。実装を確認してください。ホープコードが行われているものと言う:生産

#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; 
} 

出力:

enter image description here

必要な場合は、チューニングにしきい値を微ことができます。

+0

おかげさまで、私はなぜ「腐食してから腐食してしまいますか」と教えてください。 – user2121

+0

週に切断されたエッジ間の接続を構築するには... –

+0

私はCannyエッジ検出器を使用すれば同じ結果を得られないと思いますか? – user2121

関連する問題