第4讲:快速过一下图像基本操作(三)

目录

一、前言

二、代码片段

        1、膨胀

        2、腐蚀

        3、开运算

        4、闭运算

        5、顶帽运算

        6、黑帽运算

        7、梯度运算

        8、连通域分割

        9、连通域可视化

        10、最大连通域提取

三、完整代码

四、总结:


一、前言

        本文旨在快速过一下图像基本操作,不做过多原理解释。代码都有,具体细节可自行琢磨,举一反三。

二、代码片段

        1、膨胀

cv::Mat bin_dilate;
cv::dilate(bin, bin_dilate, element);
cv::imshow("bin_dilate", bin_dilate);
cv::waitKey(0);

        2、腐蚀

cv::Mat bin_erode;
cv::erode(bin, bin_erode, element);
cv::imshow("bin_erode", bin_erode);
cv::waitKey(0);

        3、开运算

cv::Mat bin_open;
cv::morphologyEx(bin, bin_open, cv::MORPH_OPEN, element);
cv::imshow("bin_open", bin_open);
cv::waitKey(0);

        4、闭运算

cv::Mat bin_close;
cv::morphologyEx(bin, bin_close, cv::MORPH_CLOSE, element);
cv::imshow("bin_close", bin_close);
cv::waitKey(0);

        5、顶帽运算

cv::Mat bin_top;
cv::morphologyEx(bin, bin_top, cv::MORPH_TOPHAT, element);
cv::imshow("bin_top", bin_top);
cv::waitKey(0);

        6、黑帽运算

cv::Mat bin_black;
cv::morphologyEx(bin, bin_black, cv::MORPH_BLACKHAT, element);
cv::imshow("bin_black", bin_black);
cv::waitKey(0);

        7、梯度运算

cv::Mat bin_grad;
cv::morphologyEx(bin, bin_grad, cv::MORPH_GRADIENT, element);
cv::imshow("bin_grad", bin_grad);
cv::waitKey(0);

        8、连通域分割

cv::Mat labels;
int num = cv::connectedComponents(bin, labels, 4, CV_16U); 

        9、连通域可视化

cv::Mat mat_show;
cv::normalize(labels, mat_show, 255, 0, cv::NORM_MINMAX);
cv::convertScaleAbs(mat_show, mat_show);
cv::applyColorMap(mat_show, mat_show, cv::COLORMAP_JET);
cv::imshow("mat_show", mat_show);
cv::waitKey(0);

        10、最大连通域提取

std::vector<int> num_of_labels;
for (int i = 0; i < num; i++)// 初始化 所有label的初值均设置为0
	num_of_labels.push_back(0);

int rows = labels.rows;
int cols = labels.cols;
for (int row = 0; row < rows; row++) { //计算连通域的面积
	for (int col = 0; col < cols; col++){
		num_of_labels.at(labels.at<unsigned short>(row, col)) += 1;
	}
}
num_of_labels.at(0) = 0; //将背景的labels个数设置为0

int max_label = -1;
int max_area = -1;
for (int i = 0; i < num_of_labels.size(); i++){ // 找出最大面积的label
	if (num_of_labels[i] > max_area){
		max_label = i;
		max_area = num_of_labels[i];
	}
}

cv::Mat max_connected_domain = cv::Mat::zeros(bin.size(),CV_8UC1);
for (int r = 0; r < bin.rows; r++){
	for (int c = 0; c < bin.cols; c++){
		if (labels.at<unsigned short>(r, c) == max_label){
			max_connected_domain.at<uchar>(r, c) = 255;
		}
	}
}
cv::imshow("max_connected_domain", max_connected_domain);
cv::waitKey(0);

三、完整代码

#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>

int main()
{
	cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR);

	cv::Mat src = cv::imread("people.jpg", cv::IMREAD_GRAYSCALE);
	cv::Mat bin;
	cv::threshold(src, bin, 125, 255, cv::THRESH_BINARY||cv::THRESH_OTSU);
	cv::imshow("bin", bin);
	cv::waitKey(0);

	//获取自定义形态学核
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

	// 1、膨胀	
	cv::Mat bin_dilate;
	cv::dilate(bin, bin_dilate, element);
	cv::imshow("bin_dilate", bin_dilate);
	cv::waitKey(0);

	// 2、腐蚀
	cv::Mat bin_erode;
	cv::erode(bin, bin_erode, element);
	cv::imshow("bin_erode", bin_erode);
	cv::waitKey(0);

	// 3、开运算
	cv::Mat bin_open;
	cv::morphologyEx(bin, bin_open, cv::MORPH_OPEN, element);
	cv::imshow("bin_open", bin_open);
	cv::waitKey(0);

	// 4、闭运算
	cv::Mat bin_close;
	cv::morphologyEx(bin, bin_close, cv::MORPH_CLOSE, element);
	cv::imshow("bin_close", bin_close);
	cv::waitKey(0);

	// 5、顶帽运算
	cv::Mat bin_top;
	cv::morphologyEx(bin, bin_top, cv::MORPH_TOPHAT, element);
	cv::imshow("bin_top", bin_top);
	cv::waitKey(0);

	// 6、黑帽运算
	cv::Mat bin_black;
	cv::morphologyEx(bin, bin_black, cv::MORPH_BLACKHAT, element);
	cv::imshow("bin_black", bin_black);
	cv::waitKey(0);

	// 7、梯度运算
	cv::Mat bin_grad;
	cv::morphologyEx(bin, bin_grad, cv::MORPH_GRADIENT, element);
	cv::imshow("bin_grad", bin_grad);
	cv::waitKey(0);

	// 8、连通域分割
	cv::Mat labels;
	int num = cv::connectedComponents(bin, labels, 4, CV_16U);

	// 9、将分割后的连通域可视化(同样适用于深度图等非8位图的可视化)
	cv::Mat mat_show;
	cv::normalize(labels, mat_show, 255, 0, cv::NORM_MINMAX);
	cv::convertScaleAbs(mat_show, mat_show);
	cv::applyColorMap(mat_show, mat_show, cv::COLORMAP_JET);
	cv::imshow("mat_show", mat_show);
	cv::waitKey(0);
	
	// 10、最大连通域提取
	std::vector<int> num_of_labels;
	for (int i = 0; i < num; i++)// 初始化 所有label的初值均设置为0
		num_of_labels.push_back(0);

	int rows = labels.rows;
	int cols = labels.cols;
	for (int row = 0; row < rows; row++) { //计算连通域的面积
		for (int col = 0; col < cols; col++){
			num_of_labels.at(labels.at<unsigned short>(row, col)) += 1;
		}
	}
	num_of_labels.at(0) = 0; //将背景的labels个数设置为0

	int max_label = -1;
	int max_area = -1;
	for (int i = 0; i < num_of_labels.size(); i++){ // 找出最大面积的label
		if (num_of_labels[i] > max_area){
			max_label = i;
			max_area = num_of_labels[i];
		}
	}

	cv::Mat max_connected_domain = cv::Mat::zeros(bin.size(),CV_8UC1);
	for (int r = 0; r < bin.rows; r++){
		for (int c = 0; c < bin.cols; c++){
			if (labels.at<unsigned short>(r, c) == max_label){
				max_connected_domain.at<uchar>(r, c) = 255;
			}
		}
	}
	cv::imshow("max_connected_domain", max_connected_domain);
	cv::waitKey(0);
}

四、总结:

        本文对二值图像的基本操作进行简要概述,旨在为博客后续较难内容打下基础,敬请期待。

  • 13
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值