2010-12-21 37 views
23

如何使用opencv循環顯示圖像,就好像它是一個二維數組,以獲得每個像素的RGB值?另外,對於這個操作,在iplimage上最好使用墊子嗎?使用opencv循環顯示像素

+0

可能重複:http://stackoverflow.com/questions/998429/opencv-accessing-and-taking-the-square-root-of-pixels – 2010-12-21 23:26:58

+0

我只想用這個小功能我找到。 float pixval32f(IplImage * img,int r,int c) { \t return((float *)(img-> imageData + img-> widthStep * r))[c]; } – 2010-12-22 01:06:39

+0

http://stackoverflow.com/questions/3859222/c-negative-rgb-values-of-pixels-using-opencv/3860920#3860920 – karlphillip 2010-12-22 12:59:54

回答

37

CV ::墊優於IplImage結構,因爲它簡化了你的代碼

cv::Mat img = cv::imread("lenna.png"); 
for(int i=0; i<img.rows; i++) 
    for(int j=0; j<img.cols; j++) 
     // You can now access the pixel value with cv::Vec3b 
     std::cout << img.at<cv::Vec3b>(i,j)[0] << " " << img.at<cv::Vec3b>(i,j)[1] << " " << img.at<cv::Vec3b>(i,j)[2] << std::endl; 

這是假設你需要使用RGB值加在一起。如果你不這樣做,你可以使用cv :: split來分別獲取每個通道。請參閱etarion與示例鏈接的答案。

此外,在我的情況下,你只需要灰度圖像。然後,您可以以灰度加載圖像並以uchar數組的形式訪問它。

cv::Mat img = cv::imread("lenna.png",0); 
for(int i=0; i<img.rows; i++) 
    for(int j=0; i<img.cols; j++) 
     std::cout << img.at<uchar>(i,j) << std::endl; 

UPDATE:採用分體式拿到3個通道

cv::Mat img = cv::imread("lenna.png"); 
std::vector<cv::Mat> three_channels = cv::split(img); 

// Now I can access each channel separately 
for(int i=0; i<img.rows; i++) 
    for(int j=0; j<img.cols; j++) 
     std::cout << three_channels[0].at<uchar>(i,j) << " " << three_channels[1].at<uchar>(i,j) << " " << three_channels[2].at<uchar>(i,j) << std::endl; 

// Similarly for the other two channels 

UPDATE:感謝entarion從CV :: Vec3b例如斑點複印時,我介紹了錯誤和粘貼。

3

該文檔顯示了一個寫得很好的比較不同的方式來重複Mat圖像here

最快的方法是使用C風格的指針。以下是從文檔複製的代碼:

Mat& ScanImageAndReduceC(Mat& I, const uchar* const table) 
{ 
// accept only char type matrices 
CV_Assert(I.depth() != sizeof(uchar)); 

int channels = I.channels(); 

int nRows = I.rows; 
int nCols = I.cols * channels; 

if (I.isContinuous()) 
{ 
    nCols *= nRows; 
    nRows = 1; 
} 

int i,j; 
uchar* p; 
for(i = 0; i < nRows; ++i) 
{ 
    p = I.ptr<uchar>(i); 
    for (j = 0; j < nCols; ++j) 
    { 
     p[j] = table[p[j]]; 
    } 
} 
return I; 
} 

使用at訪問元素相當慢。

請注意,如果您的操作可以使用查找表執行,則內置函數LUT是迄今爲止最快的(也在文檔中進行了描述)。

0

如果您想要逐個修改RGB像素,下面的示例將有所幫助!

void LoopPixels(cv::Mat &img) { 
    // Accept only char type matrices 
    CV_Assert(img.depth() == CV_8U); 

    // Get the channel count (3 = rgb, 4 = rgba, etc.) 
    const int channels = img.channels(); 
    switch (channels) { 
    case 1: 
    { 
     // Single colour 
     cv::MatIterator_<uchar> it, end; 
     for (it = img.begin<uchar>(), end = img.end<uchar>(); it != end; ++it) 
      *it = 255; 
     break; 
    } 
    case 3: 
    { 
     // RGB Color 
     cv::MatIterator_<cv::Vec3b> it, end; 
     for (it = img.begin<cv::Vec3b>(), end = img.end<cv::Vec3b>(); it != end; ++it) { 
      uchar &r = (*it)[2]; 
      uchar &g = (*it)[1]; 
      uchar &b = (*it)[0]; 
      // Modify r, g, b values 
      // E.g. r = 255; g = 0; b = 0; 
     } 
     break; 
    } 
    } 
}