OpenCV2.4.10之samples_cpp_tutorial-code_learn-ImgTrans(Laplace边缘检测跟Sobel边缘检测,图像重映射)
OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Laplace边缘检测和Sobel边缘检测,图像重映射)
函数Laplacian用于计算图像的Laplace边缘,函数原型为:C++: void Laplacian(InputArray src,
OutputArray dst, int ddepth,
int ksize=1, double scale=1,
double delta=0, int borderType=BORDER_DEFAULT)参数src为灰度图,dst为与src大小相同,类型相同的Laplace边缘检测后的图像,ddepth用于描述图像的位深,ksize用于计算二阶导数滤波器的孔径大小,其值为奇数。scale为计算拉普拉斯值可选比例因子。delta为叠加在dst上的可选常量值。
Sobel函数的功能为通过Sobel算子计算 图像边缘,其函数声明为:C++: void Sobel(InputArray src,
OutputArray dst, int ddepth,
int xorder, int yorder,
int ksize=3, double scale=1,
double delta=0, intborderType=BORDER_DEFAULT )
第一个参数src为输入图像,dst为输出图像,ddepth为输出图像位深,xorder与yorder分别为x方向与y方向的导数的阶数,ksize为sobel算子的大小,该值必须为奇数。
remap的功能是实现图像的重映射。映射关系为:


本系列学习笔记参考自OpenCV2.4.10之opencv\sources\samples\cpp\tutorial_code和http://www.opencv.org.cn/opencvdoc/2.3.2/html/genindex.html
在图像处理中,往往需要对图像提取有效的边缘。本博文将介绍Laplace边缘检测和Sobel边缘检测,以及图像的重映射。
1.Laplace_Demo.cpp(Laplace边缘检测)
Demo源码及注释如下:
#include "stdafx.h" //预编译头文件 /** Laplace变换检测边缘 */ #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdlib.h> #include <stdio.h> using namespace cv; /** *主函数 */ int main( int, char** argv ) { Mat src, src_gray, dst; int kernel_size = 3; int scale = 1; int delta = 0; int ddepth = CV_16S; const char* window_name = "Laplace Demo"; ///载入图片 src = imread("D:\\opencv\\lena.png"); if( !src.data ) { return -1; } ///高斯滤波器进行模糊进而去除噪声 GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT ); ///将图像转换为灰度图 cvtColor( src, src_gray, COLOR_RGB2GRAY ); ///创建窗口 namedWindow( window_name, WINDOW_AUTOSIZE ); Mat abs_dst; ///Laplace变换 Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT ); convertScaleAbs( dst, abs_dst ); ///显示 imshow( window_name, abs_dst ); waitKey(0); return 0; }运行截图:
2.Sobel_Demo.cpp(Sobel边缘检测)
demo源码及注释如下:
#include "stdafx.h" //预编译头文件 /** Sobel边缘检测Demo */ #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdlib.h> #include <stdio.h> using namespace cv; /** * 主函数 */ int main( int, char** argv ) { Mat src, src_gray; Mat grad; const char* window_name = "Sobel Demo - Simple Edge Detector"; int scale = 1; int delta = 0; int ddepth = CV_16S; ///载入图片 src = imread("D:\\opencv\\lena.png"); if( !src.data ) { return -1; } GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT ); ///转换为灰度图 cvtColor( src, src_gray, COLOR_RGB2GRAY ); ///创建窗口 namedWindow( window_name, WINDOW_AUTOSIZE ); Mat grad_x, grad_y; Mat abs_grad_x, abs_grad_y; ///X方向的梯度边缘 Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT ); convertScaleAbs( grad_x, abs_grad_x ); //Y方向的梯度边缘 Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT ); convertScaleAbs( grad_y, abs_grad_y ); ///图像总体边缘 addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad ); imshow( window_name, grad ); waitKey(0); return 0; }运行截图:
3.Remap_Demo.cpp(图像重映射)
demo源码及注释如下:
#include "stdafx.h" //预编译头文件 /** 图像重映射Demo */ #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace cv; ///全局变量 Mat src, dst; Mat map_x, map_y; const char* remap_window = "Remap demo"; int ind = 0; ///函数声明 void update_map( void ); /** * 主函数 */ int main( int, char** argv ) { ///加载图片 src = imread("D:\\opencv\\lena.png", 1 ); ///创建于src图像大小小童的dst,map_x,map_y dst.create( src.size(), src.type() ); map_x.create( src.size(), CV_32FC1 ); map_y.create( src.size(), CV_32FC1 ); ///创建窗口 namedWindow( remap_window, WINDOW_AUTOSIZE ); ///循环 for(;;) { int c = waitKey( 1000 ); if( (char)c == 27 ) { break; } ///重映射 update_map(); remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0) ); //显示结果 imshow( remap_window, dst ); } return 0; } /** * 四种类型的重映射 */ void update_map( void ) { ind = ind%4; for( int j = 0; j < src.rows; j++ ) { for( int i = 0; i < src.cols; i++ ) { switch( ind ) { case 0: //高度缩小一半,并显示在中间 if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ) { map_x.at<float>(j,i) = 2*( i - src.cols*0.25f ) + 0.5f ; map_y.at<float>(j,i) = 2*( j - src.rows*0.25f ) + 0.5f ; } else { map_x.at<float>(j,i) = 0 ; map_y.at<float>(j,i) = 0 ; } break; case 1: //图像上下颠倒 map_x.at<float>(j,i) = (float)i ; map_y.at<float>(j,i) = (float)(src.rows - j) ; break; case 2://图像左右颠倒 map_x.at<float>(j,i) = (float)(src.cols - i) ; map_y.at<float>(j,i) = (float)j ; break; case 3://图像上下颠倒的同时左右颠倒 map_x.at<float>(j,i) = (float)(src.cols - i) ; map_y.at<float>(j,i) = (float)(src.rows - j) ; break; } } } ind++; }运行截图如下:
函数原型为:C++: void remap(InputArray src,
OutputArray dst, InputArray map1,
InputArray map2, int interpolation,
int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())其中src为源图像,dst为目的图像。map1为x方向的映射关系,map2为y方向的映射关系。interpolation为插值方式。