2016-02-03 2 views
0

Я пытался использовать findContour(), чтобы получить контуры из следующих картины 123.jpgOpenCV2 findContours(), контуры размер не равен размеру иерархии

Этот код выглядит так:

Mat mat = imread("123.jpg"); 
    cv::imshow("123.jpg",mat); 

    Mat hsv; 
    cvtColor(mat,hsv,COLOR_BGR2HSV); 

    Mat dst; 
    inRange(hsv,Scalar(0,0,49),Scalar(47,165,111),dst); 
    cout<<"dst channels:"<<dst.channels()<<endl; 

    int c0=0,c255=0,other=0; 
    for(int i=0;i<dst.rows;i++){ 
     for(int j=0;j<dst.cols;j++){ 
      int v = dst.at<uchar>(i,j); 
      if(v == 0){ 
       c0++; 
      }else if(v == 255){ 
       c255++; 
      }else{ 
       other++; 
      } 
     } 
    } 

    cout<<"0 count:"<<c0<<",255 count:"<<c255<<",other value count:"<<other<<endl; 

    cv::erode(dst,dst,cv::Mat(),cv::Point(1,1),6); 
    cv::dilate(dst,dst,cv::Mat(),cv::Point(1,1),6); 

    cv::medianBlur(dst,dst,15); 
    cv::imshow("inRange",dst); 

    vector< vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
    Mat temp; 
    dst.copyTo(temp); 

    findContours(temp,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE); 

    cout<<"contours size:"<<contours.size()<<endl; 
    cout<<"hierarchy size:"<<hierarchy.size()<<endl; 

    for (int index = 0; index >= 0; index = hierarchy[index][0]) { 
     cout<<"hierarchy at:"<<index<<","<<hierarchy[index]<<endl; 
     cv::drawContours(mat,contours,index,Scalar(120,255,0)); 
    } 

    cv::imshow("contours",mat); 

    waitKey(0); 
    return 0; 

бинарное изображение как это: inRange

конечного контура изображения, как это: contours

Журнал отпечатан в окне консоли, как это: enter image description here

Я не знаю, почему размер контура меньше, чем размер иерархии. на самом деле должно быть три формы «ВНЕШНИЙ». Кажется, пропущена одна форма в контурах вывода. этот вопрос затормозил меня в течение дня, и теперь я буду сумасшедшим ... кто-нибудь знает, почему в контурах всего два элемента: я сделал что-то не так?

+1

AFAIK, когда вы назвали findContours() с параметром иерархии CV_RETR_EXTERNAL бессмысленна – sturkmen

ответ

2

Это работает, как ожидалось для меня:

contours size:3 
hierarchy size:3 
hierarchy at:0,[1, -1, -1, -1] 
hierarchy at:1,[2, 0, -1, -1] 
hierarchy at:2,[-1, 1, -1, -1] 

enter image description here

Возможные проблемы в вашем коде:

  • dst может быть неправильно инициализируется
  • dst не может быть двоичным, т.е. может иметь значения, отличные от 0 и 255

Код:

#include <opencv2/opencv.hpp> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    // Load image 
    Mat3b img = imread("path_to_image"); 

    // Convert to grayscale 
    Mat1b bin; 
    cvtColor(img, bin, COLOR_BGR2GRAY); 

    // Binarize (remove jpeg artifacts) 
    bin = bin > 100; 

    vector< vector<Point> > contours; 
    vector<Vec4i> hierarchy; 

    findContours(bin.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 

    cout << "contours size:" << contours.size() << endl; 
    cout << "hierarchy size:" << hierarchy.size() << endl; 

    for (int index = 0; index >= 0; index = hierarchy[index][0]) { 
     cout << "hierarchy at:" << index << "," << hierarchy[index] << endl; 
     cv::drawContours(img, contours, index, Scalar(120, 255, 0), 2); 
    } 

    imshow("Result", img); 
    waitKey(); 

    return 0; 
} 
+0

HI, Мики, спасибо для вашей помощи. это как i init dst: Mat mat = imread ("123.jpg"); \t Mat hsv; \t cvtColor (мат, hsv, COLOR_BGR2HSV); \t Mat dst; \t inRange (hsv, Scalar (0,0,49), Scalar (47,165,111), dst); \t cout << "channels:" << dst.channels() << endl; \t для (INT I = 0; г (I , J); \t \t \t если (v! = 0 && v!= 255) { \t \t \t \t cout << v << ","; // кажется, печатать много -1 в этом месте \t \t \t} \t \t} \t} \t резюме :: подрывать (ДСТ, ДСТ, резюме :: Mat(), резюме :: Point (1,1), 6); \t cv :: dilate (dst, dst, cv :: Mat(), cv :: Point (1,1), 6); \t cv :: medianBlur (dst, dst, 15); – Chailie

+0

Извините, поскольку я не знаю, как форматировать код в комментарии. в любом случае, похоже, что по этой причине «dst не может быть двоичным, то есть может иметь значения, отличные от 0 и 255». Я попытался напечатать весь «пиксель» в dst. есть много «-1». не знаете, почему, можете ли вы помочь проверить это? – Chailie

+0

Несомненно, вы не проверяете это правильно: 'int v = dst.at (i, j);'. Это 'uchar', а не' char'. – Miki

0

Мой VS инструмент был связан с ..\opencv\build\x64\vc12\lib и я испытывал подобные проблемы.

Я решил эту проблему, изменив ссылку на ..\opencv\build\x86\vc12\lib

Я использую Visual Studio 2010 на Windows, 7.

+1

Если у вас есть новый вопрос, пожалуйста, спросите его, нажав кнопку [Ask Question] (http://stackoverflow.com/questions/ask). Включите ссылку на этот вопрос, если это поможет обеспечить контекст. - [Из обзора] (/ review/low-quality-posts/11758737) – SergeyA

+0

Это не новый вопрос. я имею в виду, что я получаю эту проблему, потому что я использовал 64-битную библиотеку до, после того, как я перешел на 32-разрядную lib, у нее больше нет такой проблемы – Chailie

Смежные вопросы