2014-01-17 100 views
0

我正在關注this發佈以查找圖像的顏色分量。我想我會從紅色組件開始,然後着手其他組件。我寫的代碼如下。我沒有使用Linux,我正在使用Windows。分離顏色分量

#include <opencv\cv.h> 
#include <opencv2\imgproc\imgproc.hpp> 
#include <opencv2\highgui\highgui.hpp> 
#include <iostream> 
#include <stdio.h> 

using namespace std; 
using namespace cv; 

int main(int argc, char**argv) 
{ 
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1); 
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,image->nChannels); 
    uchar *pImg =(uchar*)image->imageData; 
    uchar *pRed=(uchar*)red->imageData; 
    for(int i=0;i<image->height;i++) 
    { 
     for(int j=0;j<image->width;j++) 
     { 
      red=pImg[i*image->widthStep + j*image->nChannels + 2]; 
      pRed[i*image->widthStep + j*image->nChannels + 2]=red; 
     } 
    } 
    namedWindow("Display",1); 
    cvShowImage("Display",red); 
    waitKey(0); 
    return 0; 
} 

線條

red=pImg[i*image->widthStep + j*image->nChannels + 2];

pRed[i*image->widthStep + j*image->nChannels + 2]=red;

都出現了這樣的錯誤:

A value of type uchar cannot be assigned to an entity of the type IplImage

我要去哪裏錯了?

+0

什麼將split()返回?例如,我在圖像中有2個方格,一個是紅色,另一個是藍色。現在我想要輸出只有紅色可見。將split()能夠做到這一點?我真的不知道這個功能。你能回答並給我一個能給我結果的圖像嗎? –

+0

對不起,我刪除了評論,並給出瞭如何拆分頻道的答案。 – William

回答

3

使用C++:

cv::Mat myImage; 
myImage=imread("myImage.jpg"); 
std::vector<cv::Mat> channels; 
cv::split(myImage,channels); 
imshow("Red Channel",channels[2]); 
+0

你可以發佈結果嗎?並且非常感謝 –

0

red這裏定義:

IplImage* red=cvCreateImage( ...

看起來你只是想要一個單獨的顏色值,所以你需要使用一個新的變量(我把它命名爲redValue,使其不易混淆)

for(int j=0;j<image->width;j++) 
    { 
     uchar redValue=pImg[i*image->widthStep + j*image->nChannels + 2]; 
     pRed[i*image->widthStep + j*image->nChannels + 2]=redValue; 
    } 
+1

使它成爲'uchar redValue'而不是混淆他,如果他想使用這個值做任何事情並且解釋它的值。另外,如果他不是被迫使用IplImage,我會建議他儘快切換到'cv :: Mat'。 – Micka

+0

那麼我該如何顯示紅色組件呢? –

-2

第一:如果不強制使用IplImage請切換到cv::Mat,因爲它是如此容易理解和使用的OpenCV新的C++語法!

對於你的問題:如果你想只提取紅色通道(手動就像你做的那樣,openCV可以用你的函數調用它),試試這個代碼:我已經添加了評論,

我使用這個作爲輸入圖像來進行測試:

enter image description here

#include <opencv\cv.h> 
#include <opencv2\imgproc\imgproc.hpp> 
#include <opencv2\highgui\highgui.hpp> 
#include <iostream> 
#include <stdio.h> 

using namespace std; 
using namespace cv; 

int main(int argc, char**argv) 
{ 
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1); 
    // !!! the image that shall contain the red channel must have number of channels = 1 !!! 
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,1); 
    uchar *pImg =(uchar*)image->imageData; 
    uchar *pRed=(uchar*)red->imageData; 
    for(int i=0;i<image->height;i++) 
    { 
     for(int j=0;j<image->width;j++) 
     { 
      // !!! you have to use a variable that holds the value of single channel's pixel, which is uchar in this case (values from 0 to 255) 
      uchar redVal=pImg[i*image->widthStep + j*image->nChannels + 2]; 
      // !!! since the red image has only 1 channel, be sure to use the right ->nChannels (from the 'red' image 
      pRed[i*red->widthStep + j*red->nChannels]=redVal; 
     } 
    } 
    namedWindow("Display",1); 
    cvShowImage("Display",red); 
    waitKey(0); 
    return 0; 
} 

這應該只顯示紅色通道作爲灰度圖像。

結果看起來像這樣的莉娜輸入圖像:

enter image description here

如果你想在RGB顯示,並關閉其他渠道試試這個:

#include <opencv\cv.h> 
#include <opencv2\imgproc\imgproc.hpp> 
#include <opencv2\highgui\highgui.hpp> 
#include <iostream> 
#include <stdio.h> 

using namespace std; 
using namespace cv; 

int main(int argc, char**argv) 
{ 
    IplImage* image=cvLoadImage("C:/Users/Administrator/Desktop/sample.png",1); 
    // !!! use 3 channels again because we want to display colors 
    IplImage* red=cvCreateImage(cvSize(image->width, image->height), image->depth,3); 
    uchar *pImg =(uchar*)image->imageData; 
    uchar *pRed=(uchar*)red->imageData; 
    for(int i=0;i<image->height;i++) 
    { 
     for(int j=0;j<image->width;j++) 
     { 
      // !!! you have to use a variable that holds the value of single channel's pixel, which is uchar in this case (values from 0 to 255) 
      uchar redVal=pImg[i*image->widthStep + j*image->nChannels + 2]; 
      // !!! set all channels to zero, except the red channel which is copied. be sure to use the right widthStep 
      pRed[i*red->widthStep + j*red->nChannels + 0]=0; 
      pRed[i*red->widthStep + j*red->nChannels + 1]=0; 
      pRed[i*red->widthStep + j*red->nChannels + 2]=redVal; 
     } 
    } 
    namedWindow("Display",1); 
    cvShowImage("Display",red); 
    waitKey(0); 
    return 0; 
} 

結果看起來像這樣的萊納輸入圖像:

enter image description here

+1

Red.exe中0x000000013FA012F3未處理的異常:0xC0000005:訪問衝突寫入位置0x000000000046E000。 這是錯誤和負責的行是: pRed [i * image-> widthStep + j * red-> nChannels + 2] = redVal; 你確定這個節目嗎? –

+0

我編輯過,'pRed [i * image-> widthStep + j * red-> nChannels + 2] = redVal;'是因爲'image-> widthStep'在訪問'red'元素時明顯錯誤。由於我們在紅色圖像中只有一個頻道,因此+2也是錯誤的:)。必須再次編輯它!無法測試代碼,但這兩個更改應該做到這一點我猜。 – Micka

+0

如果您不想提取紅色通道但想要將非紅色通道設置爲零,請再次編輯 – Micka