2016-10-12 11 views
0

Моя цель - обнаружить самый большой прямоугольник в изображении, независимо от того, перекошен или нет. После некоторых исследований и поиска в Google я придумал код, который теоретически должен работать, однако в половине случаев я вижу загадочные результаты.OpenCV, обнаруживающий наибольший прямоугольник, дает загадочные результаты

Я использовал OpenCV для Android, вот код:

private void find_parallels() { 
    Utils.bitmapToMat(selectedPicture,img); 
    Mat temp = new Mat(); 
    Imgproc.resize(img,temp,new Size(640,480)); 
    img = temp.clone(); 

    Mat imgGray = new Mat(); 
    Imgproc.cvtColor(img,imgGray,Imgproc.COLOR_BGR2GRAY); 

    Imgproc.GaussianBlur(imgGray,imgGray,new Size(5,5),0); 

    Mat threshedImg = new Mat(); 
    Imgproc.adaptiveThreshold(imgGray,threshedImg,255,Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY,11,2); 

    List<MatOfPoint> contours = new ArrayList<>(); 
    Mat hierarchy = new Mat(); 
    Mat imageContours = imgGray.clone(); 
    Imgproc.cvtColor(imageContours,imageContours,Imgproc.COLOR_GRAY2BGR); 

    Imgproc.findContours(threshedImg,contours,hierarchy,Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE); 
    max_area = 0; 
    int num = 0; 

    for (int i = 0; i < contours.size(); i++) { 
     area = Imgproc.contourArea(contours.get(i)); 

     if (area > 100) { 
      MatOfPoint2f mop = new MatOfPoint2f(contours.get(i).toArray()); 
      peri = Imgproc.arcLength(mop, true); 
      Imgproc.approxPolyDP(mop, approx, 0.02 * peri, true); 

      if(area > max_area && approx.toArray().length == 4) { 
       biggest = approx; 
       num = i; 
       max_area = area; 
      } 

     } 

    } 

    selectedPicture = Bitmap.createBitmap(640,480, Bitmap.Config.ARGB_8888) ; 
    Imgproc.drawContours(img,contours,num,new Scalar(0,0,255)); 
    Utils.matToBitmap(img, selectedPicture); 

    imageView1.setImageBitmap(selectedPicture);} 

В некоторых случаях это работает отлично, как можно увидеть на этом изображении (см белой линии между монитором ободком и экраном .. извините за цвет): Пример, который работает: Example that works

Однако, когда в этом образе, и большинство изображений, где экран серовато это дает сумасшедший результат. Пример, который не работает: Example that doesn't work

ответ

1

Try использование морфологии, расширяются, а затем подрывать с таким же ядром должны сделать его лучше. Или используйте pyrDown + pyrUp или просто размывайте его.

Вкратце использовать класс фильтров низких частот, потому что ваш объект интереса намного больше шума.