把一副图片用函数cvThreshold进行二值化后黑白轮廓,这是我们一直惯用方式,但是这个方式能够使用条件就是图片灰度化后灰度值相等是模块化的,而不是以一线大小的不同灰度值相隔,犹如斑马线一样。这样一般处理方式思想就是:
- 根据图片情况进行滤波,至于滤波方式与滤波次数应该根据自己意愿与图片实际情况来自行调试;
- 使用sobel算子来进行x、y求导,次数也根据自己来调试;
- 使用闭操作或者开操作来处理,把不需要点集中一起;
- 设置ROI区域进行膨胀或者腐蚀操作去掉自己不需要点
下面是我写一个代码:
// 提取图片前景.cpp : 定义控制台应用程序的入口点。
//
/*=========================================================================
名称:图像二值化轮廓
时间:2013.08
说明:把一副亮度不一样图片进行二值化,黑白轮廓
=========================================================================*/
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
int _tmain(int argc, _TCHAR* argv[])
{
//声明几个图像指针,分别用来加载本地图片与处理后图片
IplImage *src, *dst1, *dst2 , *dst3;
src = cvLoadImage("./1.jpg", 0); //加载本地待处理图片
dst1 = cvCreateImage(cvGetSize(src),IPL_DEPTH_16S, 1);
dst2 = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
dst3 = cvLoadImage("./1.jpg",0);
//进行中值滤波
for(int i =0; i<2; i++)
{
cvSmooth(src, src, 1, 3, 0, 0, 0);
}
//使用sobel算子进行求导
cvSobel(src, dst1, 1, 0, 3);
cvConvertScaleAbs(dst1, dst2, 1.8, 0); //使用线性变换转换输入数组元素成8位无符号整型
cvThreshold(dst2, dst2, 5, 255, CV_THRESH_BINARY); //二值化阀值
cvSmooth(dst2, dst2, CV_MEDIAN, 3, 0, 0, 0); //中值滤波
//进行闭运算操作,把裂开处缝合作用
cvDilate(dst2, dst2, NULL, 2);
cvErode(dst2, dst2, NULL, 4);
//===============================================================
//使用设置有不需要黑点区域为ROI,运用膨胀函数来处理掉不需要黑点
//===============================================================
cvSetImageROI(src, cvRect(280, 210, 20, 20));
cvDilate(src, src, NULL, 10);
cvResetImageROI(src);
cvSetImageROI(dst2, cvRect(280, 210, 20, 20));
cvDilate(dst2, dst2, NULL, 10);
cvResetImageROI(dst2);
cvSetImageROI(dst2, cvRect(290, 170, 30, 30));
cvDilate(dst2, dst2, NULL, 10);
cvResetImageROI(dst2);
cvSetImageROI(dst2, cvRect(80, 200, 30, 30));
cvDilate(dst2, dst2, NULL, 10);
cvResetImageROI(dst2);
cvSetImageROI(dst2, cvRect(160, 180, 30, 30));
cvDilate(dst2, dst2, NULL, 10);
cvResetImageROI(dst2);
cvSetImageROI(dst2, cvRect(100, 130, 50,50));
cvDilate(dst2, dst2, NULL, 10);
cvResetImageROI(dst2);
cvSetImageROI(dst2, cvRect(210, 150, 55,55));
cvDilate(dst2, dst2, NULL, 10);
cvResetImageROI(dst2);
//声明显示原图像与处理好之后图像窗口
cvNamedWindow("dst2");
cvNamedWindow("dst3");
cvMoveWindow("dst2", 460, 60);
cvMoveWindow("dst3", 60, 60);
//图片显示
cvShowImage("dst3", dst3);
cvShowImage("dst2", dst2);
cvSaveImage("2.jpg", dst2);
cvSaveImage("3.jpg", dst3);
cvWaitKey(0);
//销毁所有窗口与释放图片所占内存
cvDestroyAllWindows();
cvReleaseImage(&src);
cvReleaseImage(&dst1);
cvReleaseImage(&dst2);
cvReleaseImage(&dst3);
return 0;
}