测试图片为一张640 * 480的全黑图片,中间有两个大小分别为100 * 100和150 * 150的白色方块。
该测试图片可以通过下面的程序生成:
#include<iostream>
#include<opencv2/opencv.hpp>
int main()
{
cv::Mat img = cv::Mat::zeros(cv::Size(640, 480), CV_8U);
cv::Mat rect1 = img(cv::Rect(100, 100, 100, 100));
for (size_t i = 0; i < rect1.rows; i++)
{
for (size_t j = 0; j < rect1.cols; j++)
{
rect1.at<uchar>(i, j) = 255;
}
}
cv::Mat rect2 = img(cv::Rect(300, 300, 150, 150));
for (size_t i = 0; i < rect2.rows; i++)
{
for (size_t j = 0; j < rect2.cols; j++)
{
rect2.at<uchar>(i, j) = 255;
}
}
cv::imwrite("1.png", img);
return 0;
}
连通域面积计算
所有连通域面积和计算:(输出结果为32500)
#include<iostream>
#include<opencv2/opencv.hpp>
void dfs(cv::Mat& src, cv::Mat& dst, int i, int j, int& area)
{
if (i >= 0 && i < src.rows && j >= 0 && j < src.cols && src.at<uchar>(i, j) != 0 && dst.at<uchar>(i, j) == 0)
{
dst.at<uchar>(i, j) = 255;
dfs(src, dst, i - 1, j, area);
dfs(src, dst, i + 1, j, area);
dfs(src, dst, i, j - 1, area);
dfs(src, dst, i, j + 1, area);
++area;
}
}
void getarea(cv::Mat& src)
{
cv::Mat dst = cv::Mat::zeros(src.size(), CV_8U);
int area = 0;
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
if (src.at<uchar>(i, j) != 0 && dst.at<uchar>(i, j) == 0)
dfs(src, dst, i, j, area);
}
}
std::cout << area << std::endl;
}
int main()
{
cv::Mat src = cv::imread("1.png", 0);
getarea(src);
return 0;
}
每个连通域面积计算:(输出结果为10000 22500)
#include<iostream>
#include<opencv2/opencv.hpp>
void dfs(cv::Mat& src, cv::Mat& dst, int i, int j, int& area, int num)
{
if (i >= 0 && i < src.rows && j >= 0 && j < src.cols && src.at<uchar>(i, j) != 0 && dst.at<uchar>(i, j) == 0)
{
dst.at<uchar>(i, j) = 255;
dfs(src, dst, i - 1, j, area, num);
dfs(src, dst, i + 1, j, area, num);
dfs(src, dst, i, j - 1, area, num);
dfs(src, dst, i, j + 1, area, num);
++area;
}
}
void getareas(cv::Mat& src)
{
int num = 0;
cv::Mat dst = cv::Mat::zeros(src.size(), CV_8U);
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
if (src.at<uchar>(i, j) != 0 && dst.at<uchar>(i, j) == 0)
{
num++;
int area = 0;
dfs(src, dst, i, j, area, num);
std::cout << area << std::endl;
}
}
}
}
int main()
{
cv::Mat src = cv::imread("1.png", 0);
getareas(src);
return 0;
}
连通域周长计算
所有连通域周长和计算:(输出结果为1000)
#include<iostream>
#include<opencv2/opencv.hpp>
void dfs(cv::Mat& src, cv::Mat& dst, int i, int j, int& len)
{
if (i < 0 || i >= src.rows || j < 0 || j >= src.cols || src.at<uchar>(i, j) == 0)
{
len++;
return;
}
if (dst.at<uchar>(i, j) == 255)
return;
dst.at<uchar>(i, j) = 255;
dfs(src, dst, i - 1, j, len);
dfs(src, dst, i + 1, j, len);
dfs(src, dst, i, j - 1, len);
dfs(src, dst, i, j + 1, len);
}
void getlen(cv::Mat& src)
{
int len = 0;
cv::Mat dst = cv::Mat::zeros(src.size(), CV_8U);
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
if (src.at<uchar>(i, j) != 0)
{
dfs(src, dst, i, j, len);
}
}
}
std::cout << len << std::endl;
}
int main()
{
cv::Mat src = cv::imread("1.png", 0);
getlen(src);
return 0;
}
或者:
#include<iostream>
#include<opencv2/opencv.hpp>
void getlen(cv::Mat& src)
{
int len = 0;
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
if (src.at<uchar>(i, j) != 0)
{
len += 4;
if (i > 0 && src.at<uchar>(i - 1, j) != 0) len -= 2;
if (j > 0 && src.at<uchar>(i, j - 1) != 0) len -= 2;
}
}
}
std::cout << len << std::endl;
}
int main()
{
cv::Mat src = cv::imread("1.png", 0);
getlen(src);
return 0;
}
每个连通域周长计算:(输出结果为400 600)
#include<iostream>
#include<opencv2/opencv.hpp>
void dfs(cv::Mat & src, cv::Mat & dst, int i, int j, int& len, int num)
{
if (i < 0 || i >= src.rows || j < 0 || j >= src.cols || src.at<uchar>(i, j) == 0)
{
len++;
return;
}
if (dst.at<uchar>(i, j) == 255)
return;
dst.at<uchar>(i, j) = 255;
dfs(src, dst, i - 1, j, len, num);
dfs(src, dst, i + 1, j, len, num);
dfs(src, dst, i, j - 1, len, num);
dfs(src, dst, i, j + 1, len, num);
}
void getlens(cv::Mat & src)
{
int num = 0;
cv::Mat dst = cv::Mat::zeros(src.size(), CV_8U);
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
if (src.at<uchar>(i, j) != 0 && dst.at<uchar>(i, j) == 0)
{
num++;
int len = 0;
dfs(src, dst, i, j, len, num);
std::cout << len << std::endl;
}
}
}
}
int main()
{
cv::Mat src = cv::imread("1.png", 0);
getlens(src);
return 0;
}