多语言展示
当前在线:1819今日阅读:91今日分享:37

视觉图像:卷积运算及代码实现

绪:图像卷积操作即:原图像f(x),模板图像g(x),首先,将模板g(x)在原图像f(x)中移动;然后,每到一个位置,将f(x)与g(x)的定义域相交的元素进行乘积且求和,得出新的图像点;遍历所有像素点,得到卷积后的图像;模板图像又称为卷积核;
方法/步骤
1

OpenCV卷积函数filter2D():形式:CV_EXPORTS_W void filter2D( InputArray src,OutputArray dst,int ddepth,                                  InputArray kernel,Point anchor=Point(-1,-1),                                  double delta=0,int borderType=BORDER_DEFAULT );功能:利用内核实现对图像的卷积运算;参数:InputArray src: 输入图像;OutputArray dst: 输出图像,和输入图像具有相同的尺寸和通道数量;int ddepth: 目标图像深度;原图像和目标图像支持的图像深度如下:src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F    src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F    src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F    src.depth() = CV_64F, ddepth = -1/CV_64F当ddepth输入值为-1时,目标图像和原图像深度保持一致;InputArray kernel: 卷积核,一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的kernel,可以先使用split()函数将图像通道事先分开。Point anchor: 内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。double delta:在储存目标图像前可选的添加到像素的值,默认值为0int borderType:像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。

2

filter2D()示例:#include  using namespace std; using namespace cv;  int main( int argc, char** argv ) {    Mat raw_img = imread('raw.jpg',1);    if (!raw_img.data)    {        return -1;    }    imshow('before',raw_img);     Mat mask_img = (Mat_(3,3) << 0,-1,0,-1,5,-1,0,-1,0);     Mat dst_img(raw_img.rows,raw_img.cols,CV_32FC3);    Point anchor = Point(-1,-1);       filter2D(raw_img,dst_img,-1,mask_img,anchor,0,BORDER_DEFAULT);     imshow('before',raw_img);    imshow('after',dst_img);       waitKey( 0 );         return 0;    }

3

常见卷积模板:模板:矩阵方块,其数学含义是一种卷积运算;卷积运算:是加权求和的过程;所有乘积之和作为区域中心像素的新值;卷积示例:3*3的像素区域R与卷积核G的卷积运算(中心像素)R5=R1G1+R2G2+R3G3+R4G4+R5G5+R6G6+R7G7+R8G8+R9G9;常见模板如下:滤波是图像处理的基本操作,滤波去除图像中的噪声,提取感兴趣的特征,允许图像重采样。图像中的频域和空域:空间域指用图像的灰度值来描述一幅图像;而频域指用图像灰度值的变化来描述一幅图像。而低通滤波器和高通滤波器的概念就是在频域中产生的。低通滤波器:指去除图像中的高频成分,使边缘平滑;而高通滤波器:指去除图像中的低频成分,使边缘提取与增强;

4

卷积边界问题:当处理图像边界像素时,卷积核与图像使用区域不能匹配,卷积核的中心与边界像素点对应,卷积将出现问题。处理方法:A.忽略边界像素,即处理后的图像将丢掉这些像素;B.保留原边界像素,即copy边界像素到处理后的图像;

5

自定义卷积运算:#include using namespace std;using namespace cv; //kernel(-1,-2,1;4,-2,-1;4,-2,2);void Sharpen(Mat& myImage, Mat& Result){       int nChannels = myImage.channels();       Result.create(myImage.size(), myImage.type());        for (int j = 1; j < myImage.rows - 1; ++j) //hang       {              unsigned char *previous = myImageNaNr(j-1);//上一行数据的指针              unsigned char *current = myImageNaNr(j);//当前行数据的指针              unsigned char *next = myImageNaNr(j+1);//下一行数据的指针              unsigned char *output = ResultNaNr(j);  //输出图像当前列数据的指针               for (int i = 1; i < myImage.cols - 1; ++i)//lie              {                     output[i] += saturate_cast(                                      -1*previous[i-1]-2*previous[i]+1*previous[i+1]                                   +4*current[i-1]-2*current[i]-1*current[i+1]                                            +4*next[i-1]-2*next[i]+2*next[i+1]) ;               }       }       // 将边界设为0       Result.row(0).setTo(Scalar(0));       Result.row(Result.rows - 1).setTo(Scalar(0));       Result.col(0).setTo(Scalar(0));       Result.col(Result.cols - 1).setTo(Scalar(0));} int main(){        Mat img = imread('raw.jpg',0);       Mat src;       Sharpen(img, src);       imshow('img', img);       imshow('src',src);       waitKey(0);       return 0;}

6

示例:#include using namespace std;using namespace cv; Mat Gaussian_kernal(int kernel_size,float sigma);Mat z_Sharpen(Mat raw_img,Mat kernel_img); int main( int argc, char** argv ){    Mat raw_img = imread('raw.jpg',0);    imshow('before',raw_img);     int kernel_size =3;    float sigma = 1.4;    Mat kernel_img = Gaussian_kernal(kernel_size,sigma);    cout<(i);//dang qian hang                                   int m_J = -k_size;//lie            for (int m=0;m(m);                int m_I = -k_size;//hang                for (int n=0;n(i+m_I);                    current[j] += saturate_cast(p_data[j+m_J]*k_data[n]);                    m_I++;                }                m_J++;            }         }    }    //将边界设为0    for (int i=0;i(i)[j] = exp(-(x*x+y*y)/2*s_2) /(PI*s_2);        }    }    return mask_temp;}

注意事项
1

图像数据类型的转换

2

图像的像素值的访问

推荐信息