欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv学习(一)连通域分割及移动

程序员文章站 2022-07-12 23:22:40
...

连通域分割原理:
将图像二值化,并用connectedComponentsWithStats算子进行分割,将二值图分割成label,可以取label中的任何一块,如果要进行区域筛选,现成的Stats中有面积和长宽,其他特征(圆度,凸度。。。。。。)该如何选择,还有待继续研究;
连通域的旋转平移用仿射变换函数warpAffine,理解warpAffine的关键在于对第三个参数的理解,它是一个2*3的矩阵,

(1)平移,将每一点移到到(x+t , y+t),变换矩阵为

opencv学习(一)连通域分割及移动

(2)缩放变换  将每一点的横坐标放大或缩小sx倍,纵坐标放大(缩小)到sy倍,变换矩阵为

opencv学习(一)连通域分割及移动

(3)旋转变换原点:目标图形围绕原点顺时针旋转Θ 弧度,变换矩阵为

opencv学习(一)连通域分割及移动

(4) 旋转变换  :目标图形以(x , y )为轴心顺时针旋转θ弧度,变换矩阵为

opencv学习(一)连通域分割及移动

#include<opencv2/opencv.hpp>
#include<vector>
using namespace std;
using namespace cv;
int main() 
{
	Mat img_ori = imread("Search1.jpg", 0);
	Mat imgThreshold;
	Mat imgConnction;
	Mat stats; 
	Mat centroids;
	vector<uchar> test;
	

	threshold(img_ori, imgThreshold, 128, 255, THRESH_BINARY_INV); 
	connectedComponentsWithStats(imgThreshold, imgConnction, stats, centroids);
	Mat imgLable = Mat::zeros(img_ori.size(), img_ori.type());
	Mat mask = Mat::zeros(img_ori.size(), img_ori.type());
	

	for (int i = 0; i < mask.rows; i++)
	{
		for (int j = 0; j < mask.cols; j++)
		{
			if (imgConnction.at<__int32>(i, j) == 2)
			{
				mask.at<uchar>(i, j) = 255;
			}
		}
	}
	Mat mask2; cv::Mat t_mat = cv::Mat::zeros(2, 3, CV_32FC1);

	t_mat.at<float>(0, 0) = 1;
	t_mat.at<float>(0, 2) = 100; //水平平移量  
	t_mat.at<float>(1, 1) = 1;
	t_mat.at<float>(1, 2) = 100; //竖直平移量  
	warpAffine(mask, mask2, t_mat, mask.size());
	imshow("img", img_ori);
	imshow("mask1", mask);
	imshow("mask2", mask2);
	waitKey();
	return 0;
}
运行结果: