用到的函数:
cvSmooth
cvSmooth( const void* srcarr, void* dstarr, int smoothtype,int param1, int param2, double param3 )
作用:是对图象做各种方法的图象平滑。
srcarr:输入图象;
dstarr:输出图象;
param1为平滑操作的第一个参数;
param2为平滑操作的第二个参数(如果param2值为0,则表示它被设为param1);
param3是对应高斯参数的标准差。
参数smoothtype是图象平滑的方法选择,主要的平滑方法有以下五种:
CV_BLUR_NO_SCALE:简单不带尺度变换的模糊,即对每个象素在 param1×param2领域求和。
CV_BLUR:对每个象素在param1×param2邻域求和并做尺度变换 1/(param1?param2)。
CV_GAUSSIAN:对图像进行核大小为param1×param2的高斯卷积。
CV_MEDIAN:对图像进行核大小为param1×param1 的中值滤波(邻域必须是方的)。
CV_BILATERAL:双向滤波,应用双向 3x3 滤波,彩色设置为param1,空间设置为param2。
cvNot
void cvNot(const CvArr* src,CvArr* dst);
作用:将src中的每一个元素的每一位取反,然后把结果赋给dst。
cvCanny
void cvCanny( const CvArr* image, CvArr* edges, double threshold1,double threshold2, int aperture_size=3 );
作用: Canny 算法做边缘检测
image 输入图像
edges 输出的边缘图像
threshold1 第一个阈值
threshold2 第二个阈值
aperture_size Sobel 算子内核大小
cvCopy
void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
作用:把src中的数据复制到dst的内存中。
在使用这个函数之前,你必须用cvCreateImage()一类的函数先开一段内存,然后传递给dst。
mask
操作掩码是8比特单通道的数组,它指定了输出数组中被改变的元素。
cvCreateTrackbar
int cvCreateTrackbar( const char* trackbar_name, const char* window_name,
int* value, int count, CvTrackbarCallback on_change );
作用:创建trackbar并将它添加到指定的窗口。
trackbar_name 被创建的trackbar名字。
window_name 窗口名字,这个窗口将为被创建trackbar的父对象。
value 整数指针,它的值将反映滑块的位置。这个变量指定创建时的滑块位置。
count 滑块位置的最大值。最小值一直是0。
on_change 每次滑块位置被改变的时候,被调用函数的指针。这个函数应该被声明为void Foo(int);
如果没有回调函数,这个值可以设为NULL。
函数cvCreateTrackbar用指定的名字和范围来创建trackbar(滑块或者范围控制),指定与trackbar位置同步的变量,并且指定当trackbar位置被改变的时候调用的回调函数。被创建的trackbar显示在指定窗口的顶端。
代码:
// 018 canny边缘检测.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
char wndname[] = "Edge";
char tbarname[] = "Threshold";
int edge_thresh = 1;
IplImage *image = 0, *cedge = 0, *gray = 0, *edge = 0;
// 定义跟踪条的 callback 函数
void on_trackbar(int h)
{
//平滑处理
cvSmooth( gray, edge, CV_BLUR, 3, 3, 0 ); //gray平滑保存到edge
//取反
cvNot( gray, edge ); //为什么要取反?不取反的运行效果好像是一样的!
// 对灰度图像进行边缘检测
cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 3);
//矩阵清零
cvZero( cedge );
//拷贝到cedge,mask=edge,指定了输出数组中被改变的元素。
cvCopy( image, cedge, edge );
// 显示图像
cvShowImage(wndname, cedge);
// cvShowImage(wndname, edge); //单色显示
}
int main( int argc, char** argv )
{
image=cvLoadImage("Lena.jpg");
//创建输出图像
cedge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 3);
// 将彩色图像转换为灰度图像
gray = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); //灰度图像
edge = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); //灰度平滑后的图像
cvCvtColor(image, gray, CV_BGR2GRAY);
cvNamedWindow(wndname, 1);
// 创建滚动条,&edge_thresh整数指针,即滑块的位置,100为滑块位置的最大值,滑块位置每次改变都会调用on_trackbar
// 每次改变滑块位置edge_thresh的值都会改变
cvCreateTrackbar(tbarname, wndname, &edge_thresh, 100, on_trackbar);
// 显示图像,用于第一次运行程序时(没有动滑块时)的显示
on_trackbar(1);
cvWaitKey(0);
cvReleaseImage(&image);
cvReleaseImage(&gray);
cvReleaseImage(&edge);
cvDestroyWindow(wndname);
return 0;
}
运行结果: