imgproc 模块 图像处理.docx
《imgproc 模块 图像处理.docx》由会员分享,可在线阅读,更多相关《imgproc 模块 图像处理.docx(18页珍藏版)》请在冰点文库上搜索。
imgproc模块图像处理
imgproc 模块.图像处理
图像平滑处理
代码
#include
usingnamespacestd;
usingnamespacecv;
///全局变量
intDELAY_CAPTION=1500;
intDELAY_BLUR=100;
intMAX_KERNEL_LENGTH=31;
Matsrc;Matdst;
charwindow_name[]="FilterDemo1";
///函数申明
intdisplay_caption(char*caption);
intdisplay_dst(intdelay);
///main函数
intmain(intargc,char**argv)
{
namedWindow(window_name,1);
///载入原图像
src=imread("../lesson1/lena.jpg",1);
if(display_caption("OriginalImage")!
=0){return0;}
dst=src.clone();
if(display_dst(DELAY_CAPTION)!
///使用均值平滑
if(display_caption("HomogeneousBlur")!
for(inti=1;i{blur(src,dst,Size(i,i),Point(-1,-1));if(display_dst(DELAY_BLUR)!=0){return0;}}///使用高斯平滑if(display_caption("GaussianBlur")!=0){return0;}for(inti=1;i{GaussianBlur(src,dst,Size(i,i),0,0);if(display_dst(DELAY_BLUR)!=0){return0;}}///使用中值平滑if(display_caption("MedianBlur")!=0){return0;}for(inti=1;i{medianBlur(src,dst,i);if(display_dst(DELAY_BLUR)!=0){return0;}}///使用双边平滑if(display_caption("BilateralBlur")!=0){return0;}for(inti=1;i{bilateralFilter(src,dst,i,i*2,i/2);if(display_dst(DELAY_BLUR)!=0){return0;}}///等待用户输入display_caption("End:Pressakey!");waitKey(0);return0;}intdisplay_caption(char*caption){dst=Mat::zeros(src.size(),src.type());putText(dst,caption,Point(src.cols/4,src.rows/2),FONT_HERSHEY_COMPLEX,1,Scalar(255,255,255));imshow(window_name,dst);intc=waitKey(DELAY_CAPTION);if(c>=0){return-1;}return0;}intdisplay_dst(intdelay){imshow(window_name,dst);intc=waitKey(delay);if(c>=0){return-1;}return0;}结果腐蚀与膨胀代码#include#includeusingnamespacestd;usingnamespacecv; ///全局变量Matsrc,erosion_dst,dilation_dst;interosion_elem=0;interosion_size=0;intdilation_elem=0;intdilation_size=0;intconstmax_elem=2;intconstmax_kernel_size=21;/**FunctionHeaders*/voidErosion(int,void*);voidDilation(int,void*);/**@functionmain*/intmain(intargc,char**argv){///Load图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow("ErosionDemo",1);namedWindow("DilationDemo",1);moveWindow("DilationDemo",src.cols,0);///创建腐蚀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","ErosionDemo",&erosion_elem,max_elem,Erosion);createTrackbar("Kernelsize:\n2n+1","ErosionDemo",&erosion_size,max_kernel_size,Erosion);///创建膨胀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","DilationDemo",&dilation_elem,max_elem,Dilation);createTrackbar("Kernelsize:\n2n+1","DilationDemo",&dilation_size,max_kernel_size,Dilation);///DefaultstartErosion(0,0);Dilation(0,0);waitKey(0);return0;}/**@functionErosion*/voidErosion(int,void*){interosion_type;if(erosion_elem==0){erosion_type=MORPH_RECT;}elseif(erosion_elem==1){erosion_type=MORPH_CROSS;}elseif(erosion_elem==2){erosion_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(erosion_type,Size(2*erosion_size+1,2*erosion_size+1),Point(erosion_size,erosion_size));///腐蚀操作erode(src,erosion_dst,element);imshow("ErosionDemo",erosion_dst);}/**@functionDilation*/voidDilation(int,void*){intdilation_type;if(dilation_elem==0){dilation_type=MORPH_RECT;}elseif(dilation_elem==1){dilation_type=MORPH_CROSS;}elseif(dilation_elem==2){dilation_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(dilation_type,Size(2*dilation_size+1,2*dilation_size+1),Point(dilation_size,dilation_size));///膨胀操作dilate(src,dilation_dst,element);imshow("DilationDemo",dilation_dst);}结果更多形态学变换源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst;intmorph_elem=0;intmorph_size=0;intmorph_operator=0;intconstmax_operator=4;intconstmax_elem=2;intconstmax_kernel_size=21;char*window_name="MorphologyTransformationsDemo";/**回调函数申明*/voidMorphology_Operations(int,void*);/**@函数main*/intmain(){///装载图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow(window_name,1);///创建选择具体操作的trackbarcreateTrackbar("Operator:\n0:Opening-1:Closing\n2:Gradient-3:TopHat\n4:BlackHat",window_name,&morph_operator,max_operator,Morphology_Operations);///创建选择内核形状的trackbarcreateTrackbar("Element:\n0:Rect-1:Cross-2:Ellipse",window_name,&morph_elem,max_elem,Morphology_Operations);///创建选择内核大小的trackbarcreateTrackbar("Kernelsize:\n2n+1",window_name,&morph_size,max_kernel_size,Morphology_Operations);///启动使用默认值Morphology_Operations(0,0);waitKey(0);return0;}/***@函数Morphology_Operations*/voidMorphology_Operations(int,void*){//由于MORPH_X的取值范围是:2,3,4,5和6intoperation=morph_operator+2;Matelement=getStructuringElement(morph_elem,Size(2*morph_size+1,2*morph_size+1),Point(morph_size,morph_size));///运行指定形态学操作morphologyEx(src,dst,operation,element);imshow(window_name,dst);}结果∙在编译上面的代码之后,我们可以运行结果,将图片路径输入。这里使用图像: ∙这里是显示窗口的两个截图。第一幅图显示了使用交错内核和 开运算 之后的结果,第二幅图显示了使用椭圆内核和 黑帽 之后的结果。 图像金字塔源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst,tmp;char*window_name="PyramidsDemo"; intmain(){///指示说明printf("\nZoomIn-Outdemo\n");printf("------------------\n");printf("*[u]->Zoomin\n");printf("*[d]->Zoomout\n");printf("*[ESC]->Closeprogram\n\n");///测试图像-尺寸必须能被2^{n}整除src=imread("../lesson1/chicky_512.png");if(!src.data){printf("Nodata!--Exitingtheprogram\n");return-1;}tmp=src;dst=tmp;///创建显示窗口namedWindow(window_name,1);imshow(window_name,dst);///循环while(true){intc;c=waitKey(10);if((char)c==27){break;}if((char)c=='u'){pyrUp(tmp,dst,Size(tmp.cols*2,tmp.rows*2));printf("**ZoomIn:Imagex2\n");}elseif((char)c=='d'){pyrDown(tmp,dst,Size(tmp.cols/2,tmp.rows/2));printf("**ZoomOut:Image/2\n");}imshow(window_name,dst);tmp=dst;}return0;}结果∙在编译上面的代码之后,我们可以运行结果。程序调用了图像 chicky_512.jpg ,你可以在 tutorial_code/image 文件夹找到它。注意图像大小是 因此向下采样不会产生错误()。原图像如下所示:∙首先按两次‘d’连续两次向下采样 pyrDown ,结果如图:∙由于我们缩小了图像,我们也因此丢失了一些信息。通过连续按两次‘u’向上采样两次 pyrUp ,很明显图像有些失真:基本的阈值操作代码#include#includeusingnamespacestd;usingnamespacecv;///全局变量定义及赋值intthreshold_value=0;intthreshold_type=3;;intconstmax_value=255;intconstmax_type=4;intconstmax_BINARY_value=255;Matsrc,src_gray,dst;char*window_name="ThresholdDemo";char*trackbar_type="Type:\n0:Binary\n1:BinaryInverted\n2:Truncate\n3:ToZero\n4:ToZeroInverted";char*trackbar_value="Value";///自定义函数声明voidThreshold_Demo(int,void*);/***@主函数*/intmain(){///读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)src=imread("../lesson1/chicky_512.png");///将图片转换成灰度图片cvtColor(src,src_gray,1);///创建一个窗口显示图片namedWindow(window_name,1);///创建滑动条来控制阈值createTrackbar(trackbar_type,window_name,&threshold_type,max_type,Threshold_Demo);createTrackbar(trackbar_value,window_name,&threshold_value,max_value,Threshold_Demo);///初始化自定义的阈值函数Threshold_Demo(0,0);///等待用户按键。如果是ESC健则退出等待过程。while(true){intc;c=waitKey(20);if((char)c==27){break;}}} /***@自定义的阈值函数*/voidThreshold_Demo(int,void*){/*0:二进制阈值1:反二进制阈值2:截断阈值3:0阈值4:反0阈值*/threshold(src_gray,dst,threshold_value,max_BINARY_value,threshold_type);imshow(window_name,dst);}结果1.程序编译过后,从正确的路径中读取一张图片。例如,该输入图片如下所示:2.首先,阈值类型选择为反二进制阈值类型。我们希望灰度值大于阈值的变暗,即这一部分像素的灰度值设定为0。从下图中可以很清楚的看到这样的变化。(在原图中,狗的嘴和眼睛部分比图像中的其他部分要亮,在结果图中可以看到由于反二进制阈值分割,这两部分变的比其他图像的都要暗。原理具体参见本节中反二进制阈值部分解释)3.现在,阈值的类型选择为0阈值。在这种情况下,我们希望那些在图像中最黑的像素点彻底的变成黑色,而其他大于阈值的像素保持原来的面貌。其结果如下图所示:实现自己的线性滤波器代码下面这段程序做了些什么?o载入一幅图像o对图像执行 归一化块滤波器 。举例来说,如果该滤波器核的大小为 ,则它会像下面这样:程序将执行核的大小分别为3、5、7、9、11的滤波器运算。o该滤波器每一种核的输出将在屏幕上显示500毫秒#include#includeusingnamespacestd;usingnamespacecv;/**@函数main*/intmain(){///声明变量Matsrc,dst;Matkernel;Pointanchor;doubledelta;intddepth;intkernel_size;char*window_name="filter2DDemo";intc;///载入图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建窗口namedWindow(window_name,1);///初始化滤波器参数anchor=Point(-1,-1);delta=0;ddepth=-1;///循环-每隔0.5秒,用一个不同的核来对图像进行滤波intind=0;while(true){c=waitKey(500);///按'ESC'可退出程序if((char)c==27){break;}///更新归一化块滤波器的核大小kernel_size=3+2*(ind%5);kernel=Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);///使用滤波器filter2D(src,dst,ddepth,kernel,anchor,delta,BORDER_DEFAULT);imshow(window_name,dst);ind++;}
{blur(src,dst,Size(i,i),Point(-1,-1));
if(display_dst(DELAY_BLUR)!
=0){return0;}}
///使用高斯平滑
if(display_caption("GaussianBlur")!
for(inti=1;i{GaussianBlur(src,dst,Size(i,i),0,0);if(display_dst(DELAY_BLUR)!=0){return0;}}///使用中值平滑if(display_caption("MedianBlur")!=0){return0;}for(inti=1;i{medianBlur(src,dst,i);if(display_dst(DELAY_BLUR)!=0){return0;}}///使用双边平滑if(display_caption("BilateralBlur")!=0){return0;}for(inti=1;i{bilateralFilter(src,dst,i,i*2,i/2);if(display_dst(DELAY_BLUR)!=0){return0;}}///等待用户输入display_caption("End:Pressakey!");waitKey(0);return0;}intdisplay_caption(char*caption){dst=Mat::zeros(src.size(),src.type());putText(dst,caption,Point(src.cols/4,src.rows/2),FONT_HERSHEY_COMPLEX,1,Scalar(255,255,255));imshow(window_name,dst);intc=waitKey(DELAY_CAPTION);if(c>=0){return-1;}return0;}intdisplay_dst(intdelay){imshow(window_name,dst);intc=waitKey(delay);if(c>=0){return-1;}return0;}结果腐蚀与膨胀代码#include#includeusingnamespacestd;usingnamespacecv; ///全局变量Matsrc,erosion_dst,dilation_dst;interosion_elem=0;interosion_size=0;intdilation_elem=0;intdilation_size=0;intconstmax_elem=2;intconstmax_kernel_size=21;/**FunctionHeaders*/voidErosion(int,void*);voidDilation(int,void*);/**@functionmain*/intmain(intargc,char**argv){///Load图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow("ErosionDemo",1);namedWindow("DilationDemo",1);moveWindow("DilationDemo",src.cols,0);///创建腐蚀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","ErosionDemo",&erosion_elem,max_elem,Erosion);createTrackbar("Kernelsize:\n2n+1","ErosionDemo",&erosion_size,max_kernel_size,Erosion);///创建膨胀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","DilationDemo",&dilation_elem,max_elem,Dilation);createTrackbar("Kernelsize:\n2n+1","DilationDemo",&dilation_size,max_kernel_size,Dilation);///DefaultstartErosion(0,0);Dilation(0,0);waitKey(0);return0;}/**@functionErosion*/voidErosion(int,void*){interosion_type;if(erosion_elem==0){erosion_type=MORPH_RECT;}elseif(erosion_elem==1){erosion_type=MORPH_CROSS;}elseif(erosion_elem==2){erosion_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(erosion_type,Size(2*erosion_size+1,2*erosion_size+1),Point(erosion_size,erosion_size));///腐蚀操作erode(src,erosion_dst,element);imshow("ErosionDemo",erosion_dst);}/**@functionDilation*/voidDilation(int,void*){intdilation_type;if(dilation_elem==0){dilation_type=MORPH_RECT;}elseif(dilation_elem==1){dilation_type=MORPH_CROSS;}elseif(dilation_elem==2){dilation_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(dilation_type,Size(2*dilation_size+1,2*dilation_size+1),Point(dilation_size,dilation_size));///膨胀操作dilate(src,dilation_dst,element);imshow("DilationDemo",dilation_dst);}结果更多形态学变换源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst;intmorph_elem=0;intmorph_size=0;intmorph_operator=0;intconstmax_operator=4;intconstmax_elem=2;intconstmax_kernel_size=21;char*window_name="MorphologyTransformationsDemo";/**回调函数申明*/voidMorphology_Operations(int,void*);/**@函数main*/intmain(){///装载图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow(window_name,1);///创建选择具体操作的trackbarcreateTrackbar("Operator:\n0:Opening-1:Closing\n2:Gradient-3:TopHat\n4:BlackHat",window_name,&morph_operator,max_operator,Morphology_Operations);///创建选择内核形状的trackbarcreateTrackbar("Element:\n0:Rect-1:Cross-2:Ellipse",window_name,&morph_elem,max_elem,Morphology_Operations);///创建选择内核大小的trackbarcreateTrackbar("Kernelsize:\n2n+1",window_name,&morph_size,max_kernel_size,Morphology_Operations);///启动使用默认值Morphology_Operations(0,0);waitKey(0);return0;}/***@函数Morphology_Operations*/voidMorphology_Operations(int,void*){//由于MORPH_X的取值范围是:2,3,4,5和6intoperation=morph_operator+2;Matelement=getStructuringElement(morph_elem,Size(2*morph_size+1,2*morph_size+1),Point(morph_size,morph_size));///运行指定形态学操作morphologyEx(src,dst,operation,element);imshow(window_name,dst);}结果∙在编译上面的代码之后,我们可以运行结果,将图片路径输入。这里使用图像: ∙这里是显示窗口的两个截图。第一幅图显示了使用交错内核和 开运算 之后的结果,第二幅图显示了使用椭圆内核和 黑帽 之后的结果。 图像金字塔源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst,tmp;char*window_name="PyramidsDemo"; intmain(){///指示说明printf("\nZoomIn-Outdemo\n");printf("------------------\n");printf("*[u]->Zoomin\n");printf("*[d]->Zoomout\n");printf("*[ESC]->Closeprogram\n\n");///测试图像-尺寸必须能被2^{n}整除src=imread("../lesson1/chicky_512.png");if(!src.data){printf("Nodata!--Exitingtheprogram\n");return-1;}tmp=src;dst=tmp;///创建显示窗口namedWindow(window_name,1);imshow(window_name,dst);///循环while(true){intc;c=waitKey(10);if((char)c==27){break;}if((char)c=='u'){pyrUp(tmp,dst,Size(tmp.cols*2,tmp.rows*2));printf("**ZoomIn:Imagex2\n");}elseif((char)c=='d'){pyrDown(tmp,dst,Size(tmp.cols/2,tmp.rows/2));printf("**ZoomOut:Image/2\n");}imshow(window_name,dst);tmp=dst;}return0;}结果∙在编译上面的代码之后,我们可以运行结果。程序调用了图像 chicky_512.jpg ,你可以在 tutorial_code/image 文件夹找到它。注意图像大小是 因此向下采样不会产生错误()。原图像如下所示:∙首先按两次‘d’连续两次向下采样 pyrDown ,结果如图:∙由于我们缩小了图像,我们也因此丢失了一些信息。通过连续按两次‘u’向上采样两次 pyrUp ,很明显图像有些失真:基本的阈值操作代码#include#includeusingnamespacestd;usingnamespacecv;///全局变量定义及赋值intthreshold_value=0;intthreshold_type=3;;intconstmax_value=255;intconstmax_type=4;intconstmax_BINARY_value=255;Matsrc,src_gray,dst;char*window_name="ThresholdDemo";char*trackbar_type="Type:\n0:Binary\n1:BinaryInverted\n2:Truncate\n3:ToZero\n4:ToZeroInverted";char*trackbar_value="Value";///自定义函数声明voidThreshold_Demo(int,void*);/***@主函数*/intmain(){///读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)src=imread("../lesson1/chicky_512.png");///将图片转换成灰度图片cvtColor(src,src_gray,1);///创建一个窗口显示图片namedWindow(window_name,1);///创建滑动条来控制阈值createTrackbar(trackbar_type,window_name,&threshold_type,max_type,Threshold_Demo);createTrackbar(trackbar_value,window_name,&threshold_value,max_value,Threshold_Demo);///初始化自定义的阈值函数Threshold_Demo(0,0);///等待用户按键。如果是ESC健则退出等待过程。while(true){intc;c=waitKey(20);if((char)c==27){break;}}} /***@自定义的阈值函数*/voidThreshold_Demo(int,void*){/*0:二进制阈值1:反二进制阈值2:截断阈值3:0阈值4:反0阈值*/threshold(src_gray,dst,threshold_value,max_BINARY_value,threshold_type);imshow(window_name,dst);}结果1.程序编译过后,从正确的路径中读取一张图片。例如,该输入图片如下所示:2.首先,阈值类型选择为反二进制阈值类型。我们希望灰度值大于阈值的变暗,即这一部分像素的灰度值设定为0。从下图中可以很清楚的看到这样的变化。(在原图中,狗的嘴和眼睛部分比图像中的其他部分要亮,在结果图中可以看到由于反二进制阈值分割,这两部分变的比其他图像的都要暗。原理具体参见本节中反二进制阈值部分解释)3.现在,阈值的类型选择为0阈值。在这种情况下,我们希望那些在图像中最黑的像素点彻底的变成黑色,而其他大于阈值的像素保持原来的面貌。其结果如下图所示:实现自己的线性滤波器代码下面这段程序做了些什么?o载入一幅图像o对图像执行 归一化块滤波器 。举例来说,如果该滤波器核的大小为 ,则它会像下面这样:程序将执行核的大小分别为3、5、7、9、11的滤波器运算。o该滤波器每一种核的输出将在屏幕上显示500毫秒#include#includeusingnamespacestd;usingnamespacecv;/**@函数main*/intmain(){///声明变量Matsrc,dst;Matkernel;Pointanchor;doubledelta;intddepth;intkernel_size;char*window_name="filter2DDemo";intc;///载入图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建窗口namedWindow(window_name,1);///初始化滤波器参数anchor=Point(-1,-1);delta=0;ddepth=-1;///循环-每隔0.5秒,用一个不同的核来对图像进行滤波intind=0;while(true){c=waitKey(500);///按'ESC'可退出程序if((char)c==27){break;}///更新归一化块滤波器的核大小kernel_size=3+2*(ind%5);kernel=Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);///使用滤波器filter2D(src,dst,ddepth,kernel,anchor,delta,BORDER_DEFAULT);imshow(window_name,dst);ind++;}
{GaussianBlur(src,dst,Size(i,i),0,0);
///使用中值平滑
if(display_caption("MedianBlur")!
for(inti=1;i{medianBlur(src,dst,i);if(display_dst(DELAY_BLUR)!=0){return0;}}///使用双边平滑if(display_caption("BilateralBlur")!=0){return0;}for(inti=1;i{bilateralFilter(src,dst,i,i*2,i/2);if(display_dst(DELAY_BLUR)!=0){return0;}}///等待用户输入display_caption("End:Pressakey!");waitKey(0);return0;}intdisplay_caption(char*caption){dst=Mat::zeros(src.size(),src.type());putText(dst,caption,Point(src.cols/4,src.rows/2),FONT_HERSHEY_COMPLEX,1,Scalar(255,255,255));imshow(window_name,dst);intc=waitKey(DELAY_CAPTION);if(c>=0){return-1;}return0;}intdisplay_dst(intdelay){imshow(window_name,dst);intc=waitKey(delay);if(c>=0){return-1;}return0;}结果腐蚀与膨胀代码#include#includeusingnamespacestd;usingnamespacecv; ///全局变量Matsrc,erosion_dst,dilation_dst;interosion_elem=0;interosion_size=0;intdilation_elem=0;intdilation_size=0;intconstmax_elem=2;intconstmax_kernel_size=21;/**FunctionHeaders*/voidErosion(int,void*);voidDilation(int,void*);/**@functionmain*/intmain(intargc,char**argv){///Load图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow("ErosionDemo",1);namedWindow("DilationDemo",1);moveWindow("DilationDemo",src.cols,0);///创建腐蚀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","ErosionDemo",&erosion_elem,max_elem,Erosion);createTrackbar("Kernelsize:\n2n+1","ErosionDemo",&erosion_size,max_kernel_size,Erosion);///创建膨胀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","DilationDemo",&dilation_elem,max_elem,Dilation);createTrackbar("Kernelsize:\n2n+1","DilationDemo",&dilation_size,max_kernel_size,Dilation);///DefaultstartErosion(0,0);Dilation(0,0);waitKey(0);return0;}/**@functionErosion*/voidErosion(int,void*){interosion_type;if(erosion_elem==0){erosion_type=MORPH_RECT;}elseif(erosion_elem==1){erosion_type=MORPH_CROSS;}elseif(erosion_elem==2){erosion_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(erosion_type,Size(2*erosion_size+1,2*erosion_size+1),Point(erosion_size,erosion_size));///腐蚀操作erode(src,erosion_dst,element);imshow("ErosionDemo",erosion_dst);}/**@functionDilation*/voidDilation(int,void*){intdilation_type;if(dilation_elem==0){dilation_type=MORPH_RECT;}elseif(dilation_elem==1){dilation_type=MORPH_CROSS;}elseif(dilation_elem==2){dilation_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(dilation_type,Size(2*dilation_size+1,2*dilation_size+1),Point(dilation_size,dilation_size));///膨胀操作dilate(src,dilation_dst,element);imshow("DilationDemo",dilation_dst);}结果更多形态学变换源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst;intmorph_elem=0;intmorph_size=0;intmorph_operator=0;intconstmax_operator=4;intconstmax_elem=2;intconstmax_kernel_size=21;char*window_name="MorphologyTransformationsDemo";/**回调函数申明*/voidMorphology_Operations(int,void*);/**@函数main*/intmain(){///装载图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow(window_name,1);///创建选择具体操作的trackbarcreateTrackbar("Operator:\n0:Opening-1:Closing\n2:Gradient-3:TopHat\n4:BlackHat",window_name,&morph_operator,max_operator,Morphology_Operations);///创建选择内核形状的trackbarcreateTrackbar("Element:\n0:Rect-1:Cross-2:Ellipse",window_name,&morph_elem,max_elem,Morphology_Operations);///创建选择内核大小的trackbarcreateTrackbar("Kernelsize:\n2n+1",window_name,&morph_size,max_kernel_size,Morphology_Operations);///启动使用默认值Morphology_Operations(0,0);waitKey(0);return0;}/***@函数Morphology_Operations*/voidMorphology_Operations(int,void*){//由于MORPH_X的取值范围是:2,3,4,5和6intoperation=morph_operator+2;Matelement=getStructuringElement(morph_elem,Size(2*morph_size+1,2*morph_size+1),Point(morph_size,morph_size));///运行指定形态学操作morphologyEx(src,dst,operation,element);imshow(window_name,dst);}结果∙在编译上面的代码之后,我们可以运行结果,将图片路径输入。这里使用图像: ∙这里是显示窗口的两个截图。第一幅图显示了使用交错内核和 开运算 之后的结果,第二幅图显示了使用椭圆内核和 黑帽 之后的结果。 图像金字塔源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst,tmp;char*window_name="PyramidsDemo"; intmain(){///指示说明printf("\nZoomIn-Outdemo\n");printf("------------------\n");printf("*[u]->Zoomin\n");printf("*[d]->Zoomout\n");printf("*[ESC]->Closeprogram\n\n");///测试图像-尺寸必须能被2^{n}整除src=imread("../lesson1/chicky_512.png");if(!src.data){printf("Nodata!--Exitingtheprogram\n");return-1;}tmp=src;dst=tmp;///创建显示窗口namedWindow(window_name,1);imshow(window_name,dst);///循环while(true){intc;c=waitKey(10);if((char)c==27){break;}if((char)c=='u'){pyrUp(tmp,dst,Size(tmp.cols*2,tmp.rows*2));printf("**ZoomIn:Imagex2\n");}elseif((char)c=='d'){pyrDown(tmp,dst,Size(tmp.cols/2,tmp.rows/2));printf("**ZoomOut:Image/2\n");}imshow(window_name,dst);tmp=dst;}return0;}结果∙在编译上面的代码之后,我们可以运行结果。程序调用了图像 chicky_512.jpg ,你可以在 tutorial_code/image 文件夹找到它。注意图像大小是 因此向下采样不会产生错误()。原图像如下所示:∙首先按两次‘d’连续两次向下采样 pyrDown ,结果如图:∙由于我们缩小了图像,我们也因此丢失了一些信息。通过连续按两次‘u’向上采样两次 pyrUp ,很明显图像有些失真:基本的阈值操作代码#include#includeusingnamespacestd;usingnamespacecv;///全局变量定义及赋值intthreshold_value=0;intthreshold_type=3;;intconstmax_value=255;intconstmax_type=4;intconstmax_BINARY_value=255;Matsrc,src_gray,dst;char*window_name="ThresholdDemo";char*trackbar_type="Type:\n0:Binary\n1:BinaryInverted\n2:Truncate\n3:ToZero\n4:ToZeroInverted";char*trackbar_value="Value";///自定义函数声明voidThreshold_Demo(int,void*);/***@主函数*/intmain(){///读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)src=imread("../lesson1/chicky_512.png");///将图片转换成灰度图片cvtColor(src,src_gray,1);///创建一个窗口显示图片namedWindow(window_name,1);///创建滑动条来控制阈值createTrackbar(trackbar_type,window_name,&threshold_type,max_type,Threshold_Demo);createTrackbar(trackbar_value,window_name,&threshold_value,max_value,Threshold_Demo);///初始化自定义的阈值函数Threshold_Demo(0,0);///等待用户按键。如果是ESC健则退出等待过程。while(true){intc;c=waitKey(20);if((char)c==27){break;}}} /***@自定义的阈值函数*/voidThreshold_Demo(int,void*){/*0:二进制阈值1:反二进制阈值2:截断阈值3:0阈值4:反0阈值*/threshold(src_gray,dst,threshold_value,max_BINARY_value,threshold_type);imshow(window_name,dst);}结果1.程序编译过后,从正确的路径中读取一张图片。例如,该输入图片如下所示:2.首先,阈值类型选择为反二进制阈值类型。我们希望灰度值大于阈值的变暗,即这一部分像素的灰度值设定为0。从下图中可以很清楚的看到这样的变化。(在原图中,狗的嘴和眼睛部分比图像中的其他部分要亮,在结果图中可以看到由于反二进制阈值分割,这两部分变的比其他图像的都要暗。原理具体参见本节中反二进制阈值部分解释)3.现在,阈值的类型选择为0阈值。在这种情况下,我们希望那些在图像中最黑的像素点彻底的变成黑色,而其他大于阈值的像素保持原来的面貌。其结果如下图所示:实现自己的线性滤波器代码下面这段程序做了些什么?o载入一幅图像o对图像执行 归一化块滤波器 。举例来说,如果该滤波器核的大小为 ,则它会像下面这样:程序将执行核的大小分别为3、5、7、9、11的滤波器运算。o该滤波器每一种核的输出将在屏幕上显示500毫秒#include#includeusingnamespacestd;usingnamespacecv;/**@函数main*/intmain(){///声明变量Matsrc,dst;Matkernel;Pointanchor;doubledelta;intddepth;intkernel_size;char*window_name="filter2DDemo";intc;///载入图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建窗口namedWindow(window_name,1);///初始化滤波器参数anchor=Point(-1,-1);delta=0;ddepth=-1;///循环-每隔0.5秒,用一个不同的核来对图像进行滤波intind=0;while(true){c=waitKey(500);///按'ESC'可退出程序if((char)c==27){break;}///更新归一化块滤波器的核大小kernel_size=3+2*(ind%5);kernel=Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);///使用滤波器filter2D(src,dst,ddepth,kernel,anchor,delta,BORDER_DEFAULT);imshow(window_name,dst);ind++;}
{medianBlur(src,dst,i);
///使用双边平滑
if(display_caption("BilateralBlur")!
for(inti=1;i{bilateralFilter(src,dst,i,i*2,i/2);if(display_dst(DELAY_BLUR)!=0){return0;}}///等待用户输入display_caption("End:Pressakey!");waitKey(0);return0;}intdisplay_caption(char*caption){dst=Mat::zeros(src.size(),src.type());putText(dst,caption,Point(src.cols/4,src.rows/2),FONT_HERSHEY_COMPLEX,1,Scalar(255,255,255));imshow(window_name,dst);intc=waitKey(DELAY_CAPTION);if(c>=0){return-1;}return0;}intdisplay_dst(intdelay){imshow(window_name,dst);intc=waitKey(delay);if(c>=0){return-1;}return0;}结果腐蚀与膨胀代码#include#includeusingnamespacestd;usingnamespacecv; ///全局变量Matsrc,erosion_dst,dilation_dst;interosion_elem=0;interosion_size=0;intdilation_elem=0;intdilation_size=0;intconstmax_elem=2;intconstmax_kernel_size=21;/**FunctionHeaders*/voidErosion(int,void*);voidDilation(int,void*);/**@functionmain*/intmain(intargc,char**argv){///Load图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow("ErosionDemo",1);namedWindow("DilationDemo",1);moveWindow("DilationDemo",src.cols,0);///创建腐蚀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","ErosionDemo",&erosion_elem,max_elem,Erosion);createTrackbar("Kernelsize:\n2n+1","ErosionDemo",&erosion_size,max_kernel_size,Erosion);///创建膨胀TrackbarcreateTrackbar("Element:\n0:Rect\n1:Cross\n2:Ellipse","DilationDemo",&dilation_elem,max_elem,Dilation);createTrackbar("Kernelsize:\n2n+1","DilationDemo",&dilation_size,max_kernel_size,Dilation);///DefaultstartErosion(0,0);Dilation(0,0);waitKey(0);return0;}/**@functionErosion*/voidErosion(int,void*){interosion_type;if(erosion_elem==0){erosion_type=MORPH_RECT;}elseif(erosion_elem==1){erosion_type=MORPH_CROSS;}elseif(erosion_elem==2){erosion_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(erosion_type,Size(2*erosion_size+1,2*erosion_size+1),Point(erosion_size,erosion_size));///腐蚀操作erode(src,erosion_dst,element);imshow("ErosionDemo",erosion_dst);}/**@functionDilation*/voidDilation(int,void*){intdilation_type;if(dilation_elem==0){dilation_type=MORPH_RECT;}elseif(dilation_elem==1){dilation_type=MORPH_CROSS;}elseif(dilation_elem==2){dilation_type=MORPH_ELLIPSE;}Matelement=getStructuringElement(dilation_type,Size(2*dilation_size+1,2*dilation_size+1),Point(dilation_size,dilation_size));///膨胀操作dilate(src,dilation_dst,element);imshow("DilationDemo",dilation_dst);}结果更多形态学变换源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst;intmorph_elem=0;intmorph_size=0;intmorph_operator=0;intconstmax_operator=4;intconstmax_elem=2;intconstmax_kernel_size=21;char*window_name="MorphologyTransformationsDemo";/**回调函数申明*/voidMorphology_Operations(int,void*);/**@函数main*/intmain(){///装载图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建显示窗口namedWindow(window_name,1);///创建选择具体操作的trackbarcreateTrackbar("Operator:\n0:Opening-1:Closing\n2:Gradient-3:TopHat\n4:BlackHat",window_name,&morph_operator,max_operator,Morphology_Operations);///创建选择内核形状的trackbarcreateTrackbar("Element:\n0:Rect-1:Cross-2:Ellipse",window_name,&morph_elem,max_elem,Morphology_Operations);///创建选择内核大小的trackbarcreateTrackbar("Kernelsize:\n2n+1",window_name,&morph_size,max_kernel_size,Morphology_Operations);///启动使用默认值Morphology_Operations(0,0);waitKey(0);return0;}/***@函数Morphology_Operations*/voidMorphology_Operations(int,void*){//由于MORPH_X的取值范围是:2,3,4,5和6intoperation=morph_operator+2;Matelement=getStructuringElement(morph_elem,Size(2*morph_size+1,2*morph_size+1),Point(morph_size,morph_size));///运行指定形态学操作morphologyEx(src,dst,operation,element);imshow(window_name,dst);}结果∙在编译上面的代码之后,我们可以运行结果,将图片路径输入。这里使用图像: ∙这里是显示窗口的两个截图。第一幅图显示了使用交错内核和 开运算 之后的结果,第二幅图显示了使用椭圆内核和 黑帽 之后的结果。 图像金字塔源码#include#includeusingnamespacestd;usingnamespacecv;///全局变量Matsrc,dst,tmp;char*window_name="PyramidsDemo"; intmain(){///指示说明printf("\nZoomIn-Outdemo\n");printf("------------------\n");printf("*[u]->Zoomin\n");printf("*[d]->Zoomout\n");printf("*[ESC]->Closeprogram\n\n");///测试图像-尺寸必须能被2^{n}整除src=imread("../lesson1/chicky_512.png");if(!src.data){printf("Nodata!--Exitingtheprogram\n");return-1;}tmp=src;dst=tmp;///创建显示窗口namedWindow(window_name,1);imshow(window_name,dst);///循环while(true){intc;c=waitKey(10);if((char)c==27){break;}if((char)c=='u'){pyrUp(tmp,dst,Size(tmp.cols*2,tmp.rows*2));printf("**ZoomIn:Imagex2\n");}elseif((char)c=='d'){pyrDown(tmp,dst,Size(tmp.cols/2,tmp.rows/2));printf("**ZoomOut:Image/2\n");}imshow(window_name,dst);tmp=dst;}return0;}结果∙在编译上面的代码之后,我们可以运行结果。程序调用了图像 chicky_512.jpg ,你可以在 tutorial_code/image 文件夹找到它。注意图像大小是 因此向下采样不会产生错误()。原图像如下所示:∙首先按两次‘d’连续两次向下采样 pyrDown ,结果如图:∙由于我们缩小了图像,我们也因此丢失了一些信息。通过连续按两次‘u’向上采样两次 pyrUp ,很明显图像有些失真:基本的阈值操作代码#include#includeusingnamespacestd;usingnamespacecv;///全局变量定义及赋值intthreshold_value=0;intthreshold_type=3;;intconstmax_value=255;intconstmax_type=4;intconstmax_BINARY_value=255;Matsrc,src_gray,dst;char*window_name="ThresholdDemo";char*trackbar_type="Type:\n0:Binary\n1:BinaryInverted\n2:Truncate\n3:ToZero\n4:ToZeroInverted";char*trackbar_value="Value";///自定义函数声明voidThreshold_Demo(int,void*);/***@主函数*/intmain(){///读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)src=imread("../lesson1/chicky_512.png");///将图片转换成灰度图片cvtColor(src,src_gray,1);///创建一个窗口显示图片namedWindow(window_name,1);///创建滑动条来控制阈值createTrackbar(trackbar_type,window_name,&threshold_type,max_type,Threshold_Demo);createTrackbar(trackbar_value,window_name,&threshold_value,max_value,Threshold_Demo);///初始化自定义的阈值函数Threshold_Demo(0,0);///等待用户按键。如果是ESC健则退出等待过程。while(true){intc;c=waitKey(20);if((char)c==27){break;}}} /***@自定义的阈值函数*/voidThreshold_Demo(int,void*){/*0:二进制阈值1:反二进制阈值2:截断阈值3:0阈值4:反0阈值*/threshold(src_gray,dst,threshold_value,max_BINARY_value,threshold_type);imshow(window_name,dst);}结果1.程序编译过后,从正确的路径中读取一张图片。例如,该输入图片如下所示:2.首先,阈值类型选择为反二进制阈值类型。我们希望灰度值大于阈值的变暗,即这一部分像素的灰度值设定为0。从下图中可以很清楚的看到这样的变化。(在原图中,狗的嘴和眼睛部分比图像中的其他部分要亮,在结果图中可以看到由于反二进制阈值分割,这两部分变的比其他图像的都要暗。原理具体参见本节中反二进制阈值部分解释)3.现在,阈值的类型选择为0阈值。在这种情况下,我们希望那些在图像中最黑的像素点彻底的变成黑色,而其他大于阈值的像素保持原来的面貌。其结果如下图所示:实现自己的线性滤波器代码下面这段程序做了些什么?o载入一幅图像o对图像执行 归一化块滤波器 。举例来说,如果该滤波器核的大小为 ,则它会像下面这样:程序将执行核的大小分别为3、5、7、9、11的滤波器运算。o该滤波器每一种核的输出将在屏幕上显示500毫秒#include#includeusingnamespacestd;usingnamespacecv;/**@函数main*/intmain(){///声明变量Matsrc,dst;Matkernel;Pointanchor;doubledelta;intddepth;intkernel_size;char*window_name="filter2DDemo";intc;///载入图像src=imread("../lesson1/lena.jpg");if(!src.data){return-1;}///创建窗口namedWindow(window_name,1);///初始化滤波器参数anchor=Point(-1,-1);delta=0;ddepth=-1;///循环-每隔0.5秒,用一个不同的核来对图像进行滤波intind=0;while(true){c=waitKey(500);///按'ESC'可退出程序if((char)c==27){break;}///更新归一化块滤波器的核大小kernel_size=3+2*(ind%5);kernel=Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);///使用滤波器filter2D(src,dst,ddepth,kernel,anchor,delta,BORDER_DEFAULT);imshow(window_name,dst);ind++;}
{bilateralFilter(src,dst,i,i*2,i/2);
///等待用户输入
display_caption("End:
Pressakey!
");
waitKey(0);
return0;
}
intdisplay_caption(char*caption)
dst=Mat:
:
zeros(src.size(),src.type());
putText(dst,caption,
Point(src.cols/4,src.rows/2),
FONT_HERSHEY_COMPLEX,1,Scalar(255,255,255));
imshow(window_name,dst);
intc=waitKey(DELAY_CAPTION);
if(c>=0){return-1;}
intdisplay_dst(intdelay)
intc=waitKey(delay);
结果
腐蚀与膨胀
Matsrc,erosion_dst,dilation_dst;
interosion_elem=0;
interosion_size=0;
intdilation_elem=0;
intdilation_size=0;
intconstmax_elem=2;
intconstmax_kernel_size=21;
/**FunctionHeaders*/
voidErosion(int,void*);
voidDilation(int,void*);
/**@functionmain*/
///Load图像
src=imread("../lesson1/lena.jpg");
if(!
src.data)
{return-1;}
///创建显示窗口
namedWindow("ErosionDemo",1);
namedWindow("DilationDemo",1);
moveWindow("DilationDemo",src.cols,0);
///创建腐蚀Trackbar
createTrackbar("Element:
\n0:
Rect\n1:
Cross\n2:
Ellipse","ErosionDemo",
&erosion_elem,max_elem,
Erosion);
createTrackbar("Kernelsize:
\n2n+1","ErosionDemo",
&erosion_size,max_kernel_size,
///创建膨胀Trackbar
Ellipse","DilationDemo",
&dilation_elem,max_elem,
Dilation);
\n2n+1","DilationDemo",
&dilation_size,max_kernel_size,
///Defaultstart
Erosion(0,0);
Dilation(0,0);
/**@functionErosion*/
voidErosion(int,void*)
interosion_type;
if(erosion_elem==0){erosion_type=MORPH_RECT;}
elseif(erosion_elem==1){erosion_type=MORPH_CROSS;}
elseif(erosion_elem==2){erosion_type=MORPH_ELLIPSE;}
Matelement=getStructuringElement(erosion_type,
Size(2*erosion_size+1,2*erosion_size+1),
Point(erosion_size,erosion_size));
///腐蚀操作
erode(src,erosion_dst,element);
imshow("ErosionDemo",erosion_dst);
/**@functionDilation*/
voidDilation(int,void*)
intdilation_type;
if(dilation_elem==0){dilation_type=MORPH_RECT;}
elseif(dilation_elem==1){dilation_type=MORPH_CROSS;}
elseif(dilation_elem==2){dilation_type=MORPH_ELLIPSE;}
Matelement=getStructuringElement(dilation_type,
Size(2*dilation_size+1,2*dilation_size+1),
Point(dilation_size,dilation_size));
///膨胀操作
dilate(src,dilation_dst,element);
imshow("DilationDemo",dilation_dst);
更多形态学变换
源码
Matsrc,dst;
intmorph_elem=0;
intmorph_size=0;
intmorph_operator=0;
intconstmax_operator=4;
char*window_name="MorphologyTransformationsDemo";
/**回调函数申明*/
voidMorphology_Operations(int,void*);
/**@函数main*/
intmain()
///装载图像
///创建选择具体操作的trackbar
createTrackbar("Operator:
Opening-1:
Closing\n2:
Gradient-3:
TopHat\n4:
BlackHat",window_name,&morph_operator,max_operator,Morphology_Operations);
///创建选择内核形状的trackbar
Rect-1:
Cross-2:
Ellipse",window_name,
&morph_elem,max_elem,
Morphology_Operations);
///创建选择内核大小的trackbar
\n2n+1",window_name,
&morph_size,max_kernel_size,
///启动使用默认值
Morphology_Operations(0,0);
/**
*@函数Morphology_Operations
*/
voidMorphology_Operations(int,void*)
//由于MORPH_X的取值范围是:
2,3,4,5和6
intoperation=morph_operator+2;
Matelement=getStructuringElement(morph_elem,Size(2*morph_size+1,2*morph_size+1),Point(morph_size,morph_size));
///运行指定形态学操作
morphologyEx(src,dst,operation,element);
∙在编译上面的代码之后,我们可以运行结果,将图片路径输入。
这里使用图像:
∙这里是显示窗口的两个截图。
第一幅图显示了使用交错内核和 开运算 之后的结果,第二幅图显示了使用椭圆内核和 黑帽 之后的结果。
图像金字塔
Matsrc,dst,tmp;
char*window_name="PyramidsDemo";
///指示说明
printf("\nZoomIn-Outdemo\n");
printf("------------------\n");
printf("*[u]->Zoomin\n");
printf("*[d]->Zoomout\n");
printf("*[ESC]->Closeprogram\n\n");
///测试图像-尺寸必须能被2^{n}整除
src=imread("../lesson1/chicky_512.png");
{printf("Nodata!
--Exitingtheprogram\n");
return-1;}
tmp=src;
dst=tmp;
///循环
while(true)
intc;
c=waitKey(10);
if((char)c==27)
{break;}
if((char)c=='u')
{pyrUp(tmp,dst,Size(tmp.cols*2,tmp.rows*2));
printf("**ZoomIn:
Imagex2\n");
elseif((char)c=='d')
{pyrDown(tmp,dst,Size(tmp.cols/2,tmp.rows/2));
printf("**ZoomOut:
Image/2\n");
tmp=dst;
∙在编译上面的代码之后,我们可以运行结果。
程序调用了图像 chicky_512.jpg ,你可以在 tutorial_code/image 文件夹找到它。
注意图像大小是
因此向下采样不会产生错误(
)。
原图像如下所示:
∙首先按两次‘d’连续两次向下采样 pyrDown ,结果如图:
∙由于我们缩小了图像,我们也因此丢失了一些信息。
通过连续按两次‘u’向上采样两次 pyrUp ,很明显图像有些失真:
基本的阈值操作
///全局变量定义及赋值
intthreshold_value=0;
intthreshold_type=3;;
intconstmax_value=255;
intconstmax_type=4;
intconstmax_BINARY_value=255;
Matsrc,src_gray,dst;
char*window_name="ThresholdDemo";
char*trackbar_type="Type:
Binary\n1:
BinaryInverted\n2:
Truncate\n3:
ToZero\n4:
ToZeroInverted";
char*trackbar_value="Value";
///自定义函数声明
voidThreshold_Demo(int,void*);
*@主函数
///读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)
///将图片转换成灰度图片
cvtColor(src,src_gray,1);
///创建一个窗口显示图片
///创建滑动条来控制阈值
createTrackbar(trackbar_type,
window_name,&threshold_type,
max_type,Threshold_Demo);
createTrackbar(trackbar_value,
window_name,&threshold_value,
max_value,Threshold_Demo);
///初始化自定义的阈值函数
Threshold_Demo(0,0);
///等待用户按键。
如果是ESC健则退出等待过程。
c=waitKey(20);
*@自定义的阈值函数
voidThreshold_Demo(int,void*)
/*0:
二进制阈值
1:
反二进制阈值
2:
截断阈值
3:
0阈值
4:
反0阈值
threshold(src_gray,dst,threshold_value,max_BINARY_value,threshold_type);
1.程序编译过后,从正确的路径中读取一张图片。
例如,该输入图片如下所示:
2.首先,阈值类型选择为反二进制阈值类型。
我们希望灰度值大于阈值的变暗,即这一部分像素的灰度值设定为0。
从下图中可以很清楚的看到这样的变化。
(在原图中,狗的嘴和眼睛部分比图像中的其他部分要亮,在结果图中可以看到由于反二进制阈值分割,这两部分变的比其他图像的都要暗。
原理具体参见本节中反二进制阈值部分解释)
3.现在,阈值的类型选择为0阈值。
在这种情况下,我们希望那些在图像中最黑的像素点彻底的变成黑色,而其他大于阈值的像素保持原来的面貌。
其结果如下图所示:
实现自己的线性滤波器
下面这段程序做了些什么?
o载入一幅图像
o对图像执行 归一化块滤波器 。
举例来说,如果该滤波器核的大小为
,则它会像下面这样:
程序将执行核的大小分别为3、5、7、9、11的滤波器运算。
o该滤波器每一种核的输出将在屏幕上显示500毫秒
///声明变量
Matkernel;
Pointanchor;
doubledelta;
intddepth;
intkernel_size;
char*window_name="filter2DDemo";
///载入图像
///创建窗口
///初始化滤波器参数
anchor=Point(-1,-1);
delta=0;
ddepth=-1;
///循环-每隔0.5秒,用一个不同的核来对图像进行滤波
intind=0;
c=waitKey(500);
///按'ESC'可退出程序
///更新归一化块滤波器的核大小
kernel_size=3+2*(ind%5);
kernel=Mat:
ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);
///使用滤波器
filter2D(src,dst,ddepth,kernel,anchor,delta,BORDER_DEFAULT);
ind++;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2