c++ - 高斯模糊 C++(无法显示完整图像)

标签 c++ image opencv gaussian

我尝试使用 C++ (OpenCV) 进行高斯模糊操作。 这是代码

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);
}

但是当我运行程序时,图像被分成三部分。我仍然没有发现我的代码有什么问题。 T_T

这里是结果 are divided into three

请帮我解决这个问题。

最佳答案

#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);
}

我在编译您的代码时遇到了一些小问题,因此有一些额外的更改(看起来您的代码的顶部部分可能已被截断,因此缺少一些变量声明)。

无论如何,最大的变化是 getPixel 和 h_blur。

代码中的主要问题是您没有处理数据包含每个像素的三个字节(蓝色、绿色、红色)而不是一个字节的事实。因此,您的代码实际上只查看了图像的前三分之一,并且稍微调换了颜色。

关于c++ - 高斯模糊 C++(无法显示完整图像),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21544134/

相关文章:

java - 无法在 Java 中反序列化来自 C++ 的 protobuf 数据

php - cakephp上传插件-定义保存文件的目录

jquery - 当鼠标悬停在元素右侧的元素上时,在图像下方显示一个框

Python3 在网络摄像头 fps 处处理和显示网络摄像头流

c++ - 动态更改文本 qlabel

c++ - 实现后期多态性的最佳方式

javascript - 在保持图像大小的同时在响应调整大小的 Canvas 上绘制

opencv - 如何加载具有 4 个 channel 的 png 图像?

multithreading - 使用条件变量在线程之间进行通信

c++ - 使用 Telnet 测试 select()