Question

I tried to make a gaussian blur operation using c + + (OpenCV). This is the code

int mask [3][3] = {1 ,2 ,1 ,
               2 ,3 ,2 ,
               1 ,2 ,1 };

int getPixel ( unsigned char * arr , int col , int row ) {
  int sum = 0;
  for ( int j = -1; j <=1; j ++) {
    for ( int i = -1; i <=1; i ++) {
       int color = arr [( row + j ) * width + ( col + i ) ];
       sum += color * mask [ i +1][ j +1];
    }
  }
   return sum /15;
}

void h_blur ( unsigned char * arr , unsigned char * result) {
  int offset = 2 *width ;
  for ( int row =2; row < height -3; row ++) {
     for ( int col =2; col < width -3; col ++) {
        result [ offset + col ] = getPixel ( arr , col , row ) ;
     }
   offset += width ;
  }
}

int main(int argc, char** argv)
{
starttime = getTickCount();
    image_input = cvLoadImage("test.jpg", CV_LOAD_IMAGE_UNCHANGED);

width     = image_input->width;
height    = image_input->height;
widthStep = image_input->widthStep;
channels  = image_input->nChannels;

IplImage* image_output = cvCreateImage(cvGetSize(image_input),IPL_DEPTH_8U,channels);
unsigned char *h_out = (unsigned char*)image_output->imageData;
unsigned char *h_in =  (unsigned char*)image_input->imageData;

//sobel_parallel(h_in, h_out, width, height, widthStep, channels);
h_blur ( h_in , h_out) ;

endtime = getTickCount();
printf("Waktu Eksekusi = %f\n", (endtime-starttime)/getTickFrequency());
cvShowImage("CPU", image_output);
cvSaveImage("output.jpg",image_output);
cvReleaseImage(&image_output);
waitKey(0);
}

but when i run the program, the image are divided into three. I still have not found what is wrong with my code. T_T

here the result are divided into three

please help me solve this problem.

Était-ce utile?

La solution

#include <opencv2/opencv.hpp>

int mask [3][3] = {1 ,2 ,1 ,
               2 ,3 ,2 ,
               1 ,2 ,1 };

int width;
int height;
int widthStep;
int channels;

int getPixel ( unsigned char * arr , int col , int row , int k ) {
  int sum = 0;
  int denom = 0;
  for ( int j = -1; j <=1; j ++) {
    for ( int i = -1; i <=1; i ++) {
       if ((row + j) >= 0 && (row + j) < height && (col + i) >= 0 && (col + i) < width) {
         int color = arr [( row + j ) * 3 * width + ( col + i ) * 3 + k];
         sum += color * mask [ i +1][ j +1];
         denom += mask [ i +1][ j +1];
       }
    }
  }
   return sum / denom;
}

void h_blur ( unsigned char * arr , unsigned char * result) {
  for ( int row =0; row < height; row ++) {
     for ( int col =0; col < width; col ++) {
        for (int k = 0; k < 3; k++) {
          result [ 3 * row * width + 3 * col + k] = getPixel ( arr , col , row , k ) ;
        }
     }
  }
}

int main(int argc, char** argv)
{
  //starttime = getTickCount();
  IplImage *image_input = cvLoadImage("test.jpg", CV_LOAD_IMAGE_UNCHANGED);

  width     = image_input->width;
  height    = image_input->height;
  widthStep = image_input->widthStep;
  channels  = image_input->nChannels;

  IplImage* image_output = cvCreateImage(cvGetSize(image_input),IPL_DEPTH_8U,channels);
  unsigned char *h_out = (unsigned char*)image_output->imageData;
  unsigned char *h_in =  (unsigned char*)image_input->imageData;

  //sobel_parallel(h_in, h_out, width, height, widthStep, channels);
  h_blur ( h_in , h_out) ;

  //endtime = getTickCount();
  //printf("Waktu Eksekusi = %f\n", (endtime-starttime)/getTickFrequency());
  cvShowImage("input", image_input);
  cvShowImage("CPU", image_output);
  cvSaveImage("output.jpg",image_output);
  cvReleaseImage(&image_output);
  cv::waitKey(0);
}

I had a few minor issues when compiling your code, so there are a few extra changes (it seems like the top section of your code may have been cut off, so a few variable declarations are missing).

In any case, the big changes are to getPixel and h_blur.

The main problem in your code was that you did not handle the fact that the data contains three bytes (blue, green, red) for each pixel, not one byte. Because of this, your code only actually looked at the first third of the image, and it swapped around the colors a bit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top