2016-04-20 116 views
0

我是新来OpenCV我试图从目录进行图像处理,使其黑白(灰度),然后将其写入另一个文件。但是输出图像与我所期望的完全不同。也许你可以帮助我,并指出代码中的错误?OpenCV彩色图像灰色故障

#include <iostream> 
#include <opencv2/opencv.hpp> 
#include <conio.h> 
#include <string.h> 
#include <string> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/core/core.hpp> 
#include <stdio.h> 
#include <stdlib.h> 
#include "cuda_runtime.h" 
#include "device_launch_parameters.h" 

using namespace std; 

void faktorial(int InSize, char *DataIn, char *DataOut)// заголовок функции 
{ 
    for(int i = 0, j = 0; i < InSize; i += 4, j++) 
    { 
     DataOut[j] = (DataIn[i] + DataIn[i + 1] + DataIn[i + 2])/3; 
    } 

} 

int main() 
{   
     char* c = "E:\henrik-evensen-castle-valley-v03.jpg"; 

     printf("Input source of image\n Example of right directory file: E:\henrik-evensen-castle-valley-v03.jpg\n Your try:\n"); 
     char *tbLEN; 
     tbLEN = new char [1024]; 

     cin.getline(tbLEN,1024); 

     cout << tbLEN; 


     IplImage* image; 
     image = cvLoadImage(tbLEN, 1); 
     int height1 = image->height; 
     int width1 = image->width; 
     int step = image->widthStep; 
     int SizeIn = step*height1; 
     char* DatIn = image->imageData; 

     IplImage *image2 = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1); 
     char* DatOut = image2->imageData; 

     faktorial(SizeIn, DatIn, DatOut); 

     cvNamedWindow("Imagecolor"); 
     cvShowImage("Imagecolor", image); 

     cvNamedWindow("Gray"); 
     cvShowImage("Gray", image2); 
     cvWaitKey(0); 
     return 0; 
} 

Input Image Output Image

编辑: 我不需要CvtColor功能,我需要使用一个阶乘函数。

+0

是否有任何特定的原因使用C-API而不是C++ API?无论如何,您*都*包括C++头文件,并且C-API据我所知已弃用。除非有人强迫你,否则我会建议不要使用C-API。如果您使用C++ API,您的错误也可能会消失,因为它会为您处理一些事情。 –

+1

[在OpenCV中将RGB转换为黑白]可能的重复(http://stackoverflow.com/questions/1585535/convert-rgb-to-black-white-in-opencv) – Samer

+0

** Samer **很多感谢那个链接,这对我很有用,不知道我怎么能通过这个主题。 ** HannesOvrén**所以IplImage,cvSaveImage,cvCreateImage等都是C-API,对不对?在我的情况下,我需要使用Mat,imwrite和其他来自C++ API的API,对吗? – Generwp

回答

1

faktorial你认为你有3个渠道。所以,你需要通过3增加i,而不是4。另外,你需要char*数据转换为uchar*数据,从而积累工程确定:

你结束:

void faktorial(int InSize, uchar *DataIn, uchar *DataOut) 
{ 
    for (int i = 0, j = 0; i < InSize; i += 3, j++) 
    { 
     DataOut[j] = (DataIn[i] + DataIn[i + 1] + DataIn[i + 2])/3; 
    } 
} 

你可以这很容易地扩展到多渠道,如:

void faktorial2(int InSize, int nChannels, uchar *DataIn, uchar *DataOut) 
{ 
    for (int i = 0, j = 0; i < InSize; i += nChannels, j++) 
    { 
     int accum = 0; 
     for (int c = 0; c < nChannels; ++c) 
     { 
      accum += DataIn[i + c]; 
     } 
     DataOut[j] = uchar(accum/nChannels); 
    } 
} 

你一般还需要考虑图像跨步到:

void faktorial3(int rows, int cols, int in_step, int in_channels, int out_step, uchar *in, uchar *out) 
{ 
    for (int r = 0; r < rows; ++r) 
    { 
     for (int c = 0; c < cols; ++c) 
     { 
      int accum = 0; 
      for (int i = 0; i < in_channels; ++i) 
      { 
       accum += in[r*in_step + c * in_channels + i]; 
      } 
      out[r*out_step + c] = uchar(accum/in_channels); 
     } 
    } 
} 

这里完整代码的调用:

#include <opencv2/opencv.hpp> 
using namespace std; 

void faktorial3(int rows, int cols, int in_step, int in_channels, int out_step, uchar *in, uchar *out) 
{ 
    for (int r = 0; r < rows; ++r) 
    { 
     for (int c = 0; c < cols; ++c) 
     { 
      int accum = 0; 
      for (int i = 0; i < in_channels; ++i) 
      { 
       accum += in[r*in_step + c * in_channels + i]; 
      } 
      out[r*out_step + c] = uchar(accum/in_channels); 
     } 
    } 
} 

void faktorial(int InSize, uchar *DataIn, uchar *DataOut) 
{ 
    for (int i = 0, j = 0; i < InSize; i += 3, j++) 
    { 
     DataOut[j] = (DataIn[i] + DataIn[i + 1] + DataIn[i + 2])/3; 
    } 

} 

void faktorial2(int InSize, int nChannels, uchar *DataIn, uchar *DataOut) 
{ 
    for (int i = 0, j = 0; i < InSize; i += nChannels, j++) 
    { 
     int accum = 0; 
     for (int c = 0; c < nChannels; ++c) 
     { 
      accum += DataIn[i + c]; 
     } 
     DataOut[j] = uchar(accum/nChannels); 
    } 
} 

int main() 
{ 
    char tbLEN[] = "D:\\SO\\img\\barns.jpg"; 

    IplImage* image; 
    image = cvLoadImage(tbLEN, 1); 

    IplImage *image2 = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1); 

    int height1 = image->height; 
    int width1 = image->width; 
    int step = image->widthStep; 
    int SizeIn = step*height1; 
    int nChannels = image->nChannels; 
    uchar* DatIn = (uchar*)image->imageData; 
    uchar* DatOut = (uchar*)image2->imageData; 

    faktorial(SizeIn, DatIn, DatOut); 
    //faktorial2(SizeIn, nChannels, DatIn, DatOut); 
    //faktorial3(image->height, image->width, image->widthStep, image->nChannels, image2->widthStep, (uchar*)image->imageData, (uchar*)image2->imageData); 

    cvNamedWindow("Imagecolor"); 
    cvShowImage("Imagecolor", image); 

    cvNamedWindow("Gray"); 
    cvShowImage("Gray", image2); 
    cvWaitKey(0); 
    return 0; 
} 

记住,C API已经过时了。 你应该切换到C++ API。

+0

非常感谢,它的作品:) – Generwp

1

尝试cvtColor(src, bwsrc, CV_RGB2GRAY); http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html(寻找cvtColor)。

+0

问题是:我真的需要用那个函数(faktorial)来做,而不使用cvtColor和类似的东西。所以我需要拍摄这张照片,并将其传递给该功能,并从中获取黑白图像。 还是谢谢你的试用。 – Generwp

+0

因此,请检查最终图像的通道数量。这可能就是为什么你有这种效果, –

+0

我该怎么做?你能解释一下吗,我请假 – Generwp

0

您的faktorial适用于每像素4个字节的图像(并没有考虑到可能的行填充)。

从JPG图像加载每个像素3个字节,这就是为什么你会看到4个移位的鬼魂。 您可以修改faktorial或只是转换加载图像到4字节格式

image = cvLoadImage(tbLEN, 1); 
cvtColor(image, image, CV_RGB2RGBA); 
相关问题