实验四(C++)——图像形态学处理
4.1 简单的介绍
4.1.1.图像的膨胀与腐蚀
腐蚀运算:
是将图像中的像素点赋值为其局部邻域中灰度的最小值,因此图像整体灰度值减少,
图像中暗的区域变得更暗,较亮的小区域被抑制。
膨胀运算:
是将图像中的像素点赋值为其局部邻域中灰度的最大值,经过膨胀处理后,图像整体灰度值增大,图像中亮的区域扩大,较暗的小区域消失。
4.1.2.图像的开操作和闭操作
腐蚀与膨胀是形态学运算的基础,在实际检测的过程中,常常需要组合运用腐蚀与膨胀对图像进行处理。
开运算与闭运算组合使用这两种操作,在保留图像主体部分的同时,处理图像中出现的冬种杂点、空洞、小的间隙、毛糙的边缘等。合理地运用开运算与闭运算,能简化操作步骤,有效地优化目标区域,使提取出的范围更为理想。
开操作:
开运算的计算步骤是先腐蚀,后膨胀。通过腐蚀运算能去除小的非关健区域,也可以把离得很近的元素分隔开,再通过膨胀填补过度腐蚀留下的空隙。因此,通过开运算能去除孤立的、细小的点,亚滑毛糙的边缘线,同时原区域面积也不会有明显的改变,类似于一种“去毛刺”的效果。
闭操作:
先膨胀图像,然后对图像进行腐蚀。其功能是来填充物体内的细小空洞,连接邻近的物体,平滑边界,同时不明显改变面积。
4.1.3.图像的顶帽和底帽
顶帽:原图像-开运算结果
底帽:闭运算结果-原图像
4.2 获取彩色图像的灰度图像
// 读取图像,详见本专栏实验一
cv::Mat im = cv::imread(fname);
//显示灰度图像
cv::Mat gray;
cv::cvtColor(im, gray, cv::COLOR_BGR2GRAY);
cv::imshow("gray", gray);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
4.3 图像的腐蚀操作
Mat rect_kernel, cross_kernel;
rect_kernel = getStructuringElement(MORPH_RECT, Size(8, 8), Point(-1, -1)); //矩形结构元素
cross_kernel = getStructuringElement(MORPH_CROSS, Size(3, 3), Point(-1, -1)); //十字结构元素
Mat erode_img; //存放腐蚀后的图像
erode(gray, erode_img, rect_kernel);
imshow("erode_img", erode_img);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
4.4 图像的膨胀操作
Mat dilate_img; //存放膨胀后的图像
dilate(gray, dilate_img, rect_kernel);
imshow("dilate_img", dilate_img);
name = "dilate_img";
save_image(dilate_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
4.5 图像的开操作
rect_level_kernel = getStructuringElement(MORPH_RECT, Size(20, 1), Point(-1, -1)); //长方形水平结构元素
rect_vertical_kernel = getStructuringElement(MORPH_CROSS, Size(1, 20), Point(-1, -1)); //长方形垂直结构元素
Mat open_opeartion_img; //存放开操作后的图像
morphologyEx(gray, open_opeartion_img, MORPH_OPEN, rect_level_kernel);
imshow("open_opeartion_img", open_opeartion_img);
name = "open_opeartion_img";
save_image(open_opeartion_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
4.6 图像的闭操作
Mat close_opeartion_img; //存放闭操作后的图像
morphologyEx(gray, close_opeartion_img, MORPH_CLOSE, rect_kernel);
imshow("close_opeartion_img", close_opeartion_img);
name = "close_opeartion_img";
save_image(close_opeartion_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
4.7 综合移植代码
//*************************************************************************************
// 函数名称 图像形态学处理
// 参数说明 gray 灰度图像原数组
// 备注信息
//*************************************************************************************
void Img_Morphology_Extract(Mat gray)
{
//生成用于腐蚀的测试图像,测试用,可删除
Mat src = (Mat_<uchar>(6, 6) << 0, 0, 0, 0, 255, 0,
0, 255, 255, 255, 255, 255,
0, 255, 255, 255, 255, 0,
0, 255, 255, 255, 255, 0,
0, 255, 255, 255, 255, 0,
0, 0, 0, 0, 0, 0);
Mat rect_kernel, cross_kernel, rect_level_kernel, rect_vertical_kernel;
rect_kernel = getStructuringElement(MORPH_RECT, Size(8, 8), Point(-1, -1)); //矩形结构元素
cross_kernel = getStructuringElement(MORPH_CROSS, Size(3, 3), Point(-1, -1)); //十字结构元素
Mat erode_img; //存放腐蚀后的图像
erode(gray, erode_img, rect_kernel);
imshow("erode_img", erode_img);
std::string name = "erode_img";
save_image(erode_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
Mat dilate_img; //存放膨胀后的图像
dilate(gray, dilate_img, rect_kernel);
imshow("dilate_img", dilate_img);
name = "dilate_img";
save_image(dilate_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
rect_level_kernel = getStructuringElement(MORPH_RECT, Size(20, 1), Point(-1, -1)); //长方形水平结构元素
rect_vertical_kernel = getStructuringElement(MORPH_CROSS, Size(1, 20), Point(-1, -1)); //长方形垂直结构元素
Mat open_opeartion_img; //存放开操作后的图像
morphologyEx(gray, open_opeartion_img, MORPH_OPEN, rect_level_kernel);
imshow("open_opeartion_img", open_opeartion_img);
name = "open_opeartion_img";
save_image(open_opeartion_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
Mat close_opeartion_img; //存放闭操作后的图像
morphologyEx(gray, close_opeartion_img, MORPH_CLOSE, rect_kernel);
imshow("close_opeartion_img", close_opeartion_img);
name = "close_opeartion_img";
save_image(close_opeartion_img, root, name);
while (waitKey(1) != ' ');
cv::destroyAllWindows();
}