2016-04-20 115 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); 
相關問題