2016-04-20 2 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

EDIT: не нужна функция CvtColor, мне нужно использовать эту одну функцию факториала.

+0

Есть ли какая-то конкретная причина, по которой вы используете C-API, а не C++ API? Вы все равно *, включая заголовки C++, и C-API, насколько я знаю, устарел. Если кто-то не заставляет вас, я бы рекомендовал не использовать C-API. Вероятно, ваша ошибка исчезнет, ​​если вы используете C++ API, так как он заботится о некоторых вещах для вас. –

+1

Возможный дубликат [Конвертировать RGB в Black & White в OpenCV] (http://stackoverflow.com/questions/1585535/convert-rgb-to-black-white-in-opencv) – Samer

+0

** Samer ** много спасибо за эту ссылку, это очень полезно для меня, не знаю, как я мог бы передать эту тему. ** Hannes Ovrén ** Итак, IplImage, cvSaveImage, cvCreateImage и т. Д. Являются C-API, правильно? И в моем случае мне нужно использовать Mat, imwrite и другие, которые из C++ API, я прав? – Generwp

ответ

1

В faktorial вы предполагаете, у вас есть 3 канала. Таким образом, вам нужно увеличить i на 3, а не 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); 
Смежные вопросы