2016-01-11 5 views
0

Я хочу перебрать бинаризованный cv::Mat и сохранить все координаты пикселей со значением 255.Как сохранить векторные координаты белых пикселей?

cv::Mat bin;              
std::vector<cv::Point2i> binVec; 
int h = 0; 
int white = 254; //Just for comparison with pointer of Matrix value 
for (int i = 0; i < bin.rows; i++, h++) { 
    for (int j = 0; j < bin.cols; j++, h++) { 
     int* p = bin.ptr<int>(h); //Pointer to bin Data, should loop through Matrix 
     if (p >= &white)   //If a white pixel has been found, push i and j in binVec 
      binVec.push_back(cv::Point2i(i, j)); 
    } 
} 

Этот снипп не работает, и я не знаю почему.

Исключение бросили в 0x76C6C42D в example.exe: исключение Microsoft C++: cv :: Исключение в ячейке памяти 0x0019E4F4.

Необработанное исключение в 0x76C6C42D в example.exe: исключение Microsoft C++: cv :: Исключение в ячейке памяти 0x0019E4F4.

Так как я могу считать h и пусть указатель работает?

+0

Вы использовали отладчик? – Drop

+0

вы не инициализируете 'h' – user463035818

+0

oh yea, когда я сжал свой код, я забыл взять инициализацию, я отредактирую код. – Flippy

ответ

4

Вы можете избежать сканирования изображения. Для того, чтобы сохранить координаты всех белых пикселей в векторе можно сделать так:

Mat bin; 
// fill bin with some value 

std::vector<Point> binVec; 
findNonZero(bin == 255, binVec); 

Вы можете использовать Point вместо Point2i, так как они одни и те же:

typedef Point2i Point; 

Если вы действительно хотите использовать цикл for, вы должны сделать следующее:

const uchar white = 255; 
for (int r = 0; r < bin.rows; ++r) 
{ 
    uchar* ptr = bin.ptr<uchar>(r); 
    for(int c = 0; c < bin.cols; ++c) 
    { 
     if (ptr[c] == 255) { 
      binVec.push_back(Point(c,r)); 
     } 
    } 
} 

Помните, что:

  • вы бинарное изображение, вероятно, CV_8UC1, а не CV_32SC1, поэтому вы должны использовать uchar вместо int.
  • bin.ptr<...>(i) дает вам указатель на начало i-й строки, поэтому вы должны вытащить его из внутреннего цикла.
  • Вы должны сравнить значения, а не адрес.
  • Point принимают в качестве параметров x (COLS) и y (строки), в то время как вы передаете i (строки) и j (COLS). Поэтому вам нужно поменять их.
  • этот цикл может быть дополнительно оптимизирован, но для вашей задачи я настоятельно рекомендую подход findNonZero, поэтому я не показываю его здесь.
+0

Спасибо за ваше время и помощь – Flippy

0
  1. Вы должны увеличивать только h во внутреннем цикле
  2. Вы должны сравнить стоимость, на которую указывает p с h, не сравнить p с адресом h.

Так

cv::Mat bin;              
std::vector<cv::Point2i> binVec; 

int h = 0; 
int white = 254; //Just for comparison with pointer of Matrix value 
for (int i = 0; i < bin.rows; i++) { 
    for (int j = 0; j < bin.cols; j++) { 
     int* p = bin.ptr<int>(h++); //Pointer to bin Data, should loop through Matrix 
     if (*p >= white)   //If a white pixel has been found, push i and j in binVec 
      binVec.push_back(cv::Point2i(i, j)); 
    } 
} 
+0

Большое спасибо, но я отвечу Miki – Flippy

+0

Это будет потому, что: 1. У меня есть определение bin.ptr неправильно. 2. Я не указал на ловушку CV_8UC1. 3. Я не указывал встроенную функцию, чтобы выполнять тяжелую работу. tl; dr - Его лучший ответ. –

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