2012-06-12 3 views
4

Я работаю с изображениями на C++ с OpenCV.Как заполнить массив Vec3b

Я написал код с массивом uchar двух измерений, где я могу читать значения пикселей изображения, загруженные с imread в оттенках серого, используя .at< uchar>(i,j).

Однако я хотел бы сделать то же самое для цветных изображений. Поскольку я знаю, что для доступа к значениям пикселей мне теперь нужны .at< Vec3b>(i,j)[0], .at< Vec3b>(i,j)[1] и .at< Vec3b>(i,j)[2], я сделал аналогичные массивы Vec3b 2d.

Но я не знаю, как заполнить этот массив значениями пикселей. Он должен быть двумерным массивом.

Я пробовал:

array[width][height].val[0]=img.at< Vec3b>(i,j)[0] 

, но это не сработало.

Не нашли ответа на документ OpenCV или нет ни здесь.

У кого-нибудь есть идея?

Я включил часть своего кода. Мне нужен массив, потому что у меня уже есть весь алгоритм, работающий с использованием массива, для изображений в оттенках серого только с одним каналом.

Серая шкала код так:

for(int i=0;i<height;i++){ 
    for(int j=0;j<width;j++){ 
     image_data[i*width+j]=all_images[nb_image-1].at< uchar>(i,j); 
    } 
} 

Где читать:

std::vector< cv::Mat> all_images 

каждое изображение (я имею длинную последовательность), извлекает значения пикселя в массиве Uchar image_data, и обрабатывает их.

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

На этот раз image_data является массив Vec3b, и код, который я пытаюсь выглядит так:

for(int i=0;i<height;i++){ 
    for(int j=0;j<width;j++){ 
     image_data[0][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[2]; 
     image_data[1][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[1]; 
     image_data[2][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[0]; 
    } 
} 

Но это не работает, так что теперь я в догадках, я не знаю, как успешно заполнить массив image_data значениями всех трех каналов без изменения структуры кода, так как этот массив используется в моем алгоритме обработки изображений.

ответ

2

Вот код, который я только что протестировал, и он работает.

#include <iostream> 
#include <cstdlib> 
#include <opencv/cv.h> 
#include <opencv/highgui.h> 

int main(int argc, char**argv){ 

    cv::Mat img = cv::imread("image.jpg",1); 
    cv::imshow("image",img); 
    cv::waitKey(0); 
    cv::Vec3b firstline[img.cols]; 
    for(int i=0;i<img.cols;i++){ 
    // access to matrix 
    cv::Vec3b tmp = img.at<cv::Vec3b>(0,i); 
    std::cout << (int)tmp(0) << " " << (int)tmp(1) << " " << (int)tmp(2) << std::endl; 
    // access to my array 
    firstline[i] = tmp; 
    std::cout << (int)firstline[i](0) << " " << (int)firstline[i](0) << " " << (int)firstline[i](0) << std::endl; 
    } 
    return EXIT_SUCCESS; 
} 
+0

Erf, к сожалению, он по какой-то причине не работает с моим кодом. Я не очень хочу публиковать его здесь, поэтому я разрешу свою проблему, найдя другой путь. Спасибо за помощь, но ваше решение действительно работает, поэтому я проверю его. – George

+0

, хотя я считаю, что он должен быть (int) tmp [0] not (int) tmp (0) (и т. Д.) – George

+0

В официальной документации opencv оператор (int) реализован для матрицы строк cv :: Matx. cv :: Vec3b получен из cv :: Matx. – Eric

3

Я не совсем понимаю, что вы пытаетесь сделать. Вы можете сразу прочитать цветное изображение с:

cv::Mat img = cv::imread("image.jpeg",1);

Ваша матрица (img) типа будет CV_8UC3, то вы можете получить доступ к каждому пикселю, как вы сказали, используя:

img.at<cv::Vec3b>(row,col)[channel].

Если у вас есть 2D массив Vec3b в Vec3b myArray[n][m]; Вы можете получить доступ к значениям так:

myArray[i][j](k) где к = {1,2,3}, так как Vec3b является матрица-строка.

+0

Да что я хочу сделать это последнее предложение, однако этот код не работает. Также нет myArray [i] [j] [k] Я не знаю, как это сделать! – George

+0

Не могли бы вы разместить весь код PLZ, чтобы мы могли его отладить. В противном случае, зачем вам нужен массив, поскольку cv :: Mat имеет доступ к данным T *. – Eric

+0

Я отредактировал свой первый пост с более ясными объяснениями и фрагментами кода, он был слишком длинным и не помещался здесь в комментарии. – George

0

В вас отредактирован первое сообщение, эта линия странно:

image_data[0][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[2]; 

Если данные изображения вашего цветного изображения, то оно должно быть написано так:

image_data[i][j] = all_images[nb_image-1].at<cv::Vec3b>(i,j); 
+0

Как-то это не работает, я не понял, откуда эта проблема возникает, но похоже, что это больше из моей части выделения памяти, когда is и js слишком высоки, она сработает, но в противном случае работает. И сейчас это меня озадачивает, потому что у меня такой же код с тем же распределением, который отлично работает, когда есть только один канал. Я работаю над этим, если я не могу решить это скоро, я думаю, я возьму другой метод. Как и три массива, аналогичные тем, которые я использую для оттенков серого, по 1 для каждого канала. Это звучит тяжело и громоздко. И я думаю, что я тоже не очень ясен. Пойдемте об этом и thx за попытку – George

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