opencv学习(一)连通域分割及移动
程序员文章站
2022-07-12 23:22:40
...
连通域分割原理:
将图像二值化,并用connectedComponentsWithStats算子进行分割,将二值图分割成label,可以取label中的任何一块,如果要进行区域筛选,现成的Stats中有面积和长宽,其他特征(圆度,凸度。。。。。。)该如何选择,还有待继续研究;
连通域的旋转平移用仿射变换函数warpAffine,理解warpAffine的关键在于对第三个参数的理解,它是一个2*3的矩阵,
(1)平移,将每一点移到到(x+t , y+t),变换矩阵为
(2)缩放变换 将每一点的横坐标放大或缩小sx倍,纵坐标放大(缩小)到sy倍,变换矩阵为
(3)旋转变换原点:目标图形围绕原点顺时针旋转Θ 弧度,变换矩阵为
(4) 旋转变换 :目标图形以(x , y )为轴心顺时针旋转θ弧度,变换矩阵为
#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;
}
运行结果:
推荐阅读