OpenCV图像变换(一)卷积

来源:互联网 发布:阿里云如何查看发票 编辑:程序博客网 时间:2024/06/04 05:30

最近在学习OpenCV中的图像变换方面的知识,想就前面的学习进行个简单的总结。图像的变换就是将一幅图像转变成图像数据的另外一种表现形式。图像的变换有很多内容,主要涉及到图像的卷积滤波、扭曲、拉伸、霍夫变换、离散傅里叶变换等等。在这篇博文中,我们将先从图像的卷积开始讨论。

(1)卷积

关于卷积的数学理论,我们在信号与系统或者是积分变换的教材中已经多次提到,对于一维卷积通俗的来说,实际的过程就是f(x)先做一个Y轴的反转,然后再沿X轴平移t就是f(t-x),然后再把g(x)拿来,两者乘积的值再积分.想象一下如果g(x)或者f(x)是个单位的阶越函数。那么就是f(t-x)与g(x)相交部分的面积。而对于图像,我们可以定义图像为I(x,y),核为G(i,j),参考点位于相应核的(ai,aj)坐标上,则卷积H(x,y)定义如下:
这里写图片描述

一个特殊的卷积所实现的功能是由其卷积核的形式决定的。这个核的本质是一个大小固定、由数值参数构成的数组,数组的参考点通常位于数组的中心。数组的大小称为核支撑。

在OpenCV中,有函数cvFilter2D()来完成这样的操作。下面对这个函数做个简单的介绍。

void cvFilter2D(    const CvArr* src,    CvArr* dst,//源图像src和目标图像dst大小应该相同    const CvMat* kernel,//卷积核,单通道浮点矩阵    CvPoint anchor=cvPoint(-1,-1)//设置参考点为核的中心)

(2)卷积边界

在刚才的介绍上,我们注意到一个问题,就是在函数cvFilter2D()函数中提及到源图像src和目标图像dst大小应该相同,但是也会出现大小不同的情况,那么OpenCV是怎么处理这种情况的呢?在默认的情况下,在卷积之前,OpenCV通过复制源图像src的边界创建了虚拟像素,这样以便于目标图像dst边界的像素可以被填充。但同时在OpenCV中也有函数cvCopyMakeBorder()函数,它可以将特定的图像轻微变大,然后以各种方式自动填充图像边界。下面简介下这个函数。

void cvCopyMakeBorder(    const CvArr* src,    CvArr* dst,    CvPoint offset,    int bordertype,    CvScalar value=cvScalarAll(0))

当调用OpenCV库函数中的卷积功能时,cvCopyMakeBorder()函数就会被自动调用,所以不用重复编辑这个函数。

(3)程序实例

#include<opencv2/opencv.hpp>#include<iostream>int main( ){    IplImage* src, *dst;    float k[9] = { 1.0, -2.0, 1.0, 4.0,        -2.0, -1.0, 4.0, -2.0, 2.0 };  //核    CvMat km = cvMat(3, 3, CV_32FC1, k);  //构造单通道浮点矩阵,将图像IplImage结构转换为图像数组    src = cvLoadImage("lena.JPG",CV_LOAD_IMAGE_UNCHANGED);    dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);    cvNamedWindow("src", 0);    cvShowImage("src", src);    cvNamedWindow("Filtering", 0);    cvFilter2D(src, dst, &km, cvPoint(-1, -1));  //设参考点为核的中心    cvShowImage("Filtering", dst);    cvWaitKey(0);    cvReleaseImage(&src);    cvReleaseImage(&dst);    return 0;}

最后的运行结果如图:
这里写图片描述

0 0
原创粉丝点击