2014-01-17 62 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