联 通 组 件 扫 描 及 带 统 计 信 息 的 联 通 组 件 扫 描 联通组件扫描及带统计信息的联通组件扫描 联通组件扫描及带统计信息的联通组件扫描
1.视频教程:
B站、网易云课堂、腾讯课堂
2.代码地址:
Gitee
Github
3.存储地址:
Google云
百度云:
提取码:
OpenCV中进行连通组件扫码调用的时候必须保证背景像素是黑色、前景像素是白色
1.联通组件扫描
1.1 联通组件
CCL:联通组件标记
1.2 四邻域和八邻域
1.3 常用算法
1.3.1 基于像素扫描的方法
1.3.1 基于块扫描的方法
1.3.1 两步法扫描
两步法扫描:基于扫描与等价类合并算法
第一步:(从上到下,从左到右,扫描像素点,并进行标记,统计等价队列标签)
第二步:(选择每个等价队列标签中最小的标签作为联通组件的标签)
带统计信息的联通组件扫描
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
GaussianBlur(src, src, Size(3, 3), 0);
Mat gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);
Mat labels = Mat::zeros(binary.size(), CV_32S);
int num_labels = connectedComponents(binary, labels, 8, CV_32S,CCL_DEFAULT);
printf("total labels : %d \n", (num_labels - 1));
waitKey(0);
destroyAllWindows();
return 0;
}
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
RNG rng(12345);
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
GaussianBlur(src, src, Size(3, 3), 0);
Mat gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);
Mat labels = Mat::zeros(binary.size(), CV_32S);
int num_labels = connectedComponents(binary, labels, 8, CV_32S,CCL_DEFAULT);
vector<Vec3b> colorTable(num_labels);
// backgound color
colorTable[0] = Vec3b(0, 0, 0);
for (int i = 1; i < num_labels; i++) {
colorTable[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
}
Mat result = Mat::zeros(src.size(),src.type());
int w = result.cols;
int h = result.rows;
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
int label = labels.at<int>(row, col);
result.at<Vec3b>(row, col) = colorTable[label];
}
}
printf("total labels : %d \n", (num_labels - 1));
imshow("CCL demo", result);
waitKey(0);
destroyAllWindows();
return 0;
}
带统计信息的联通组件扫描
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
RNG rng(12345);
void ccl_stats_demo(Mat &image);
int main(int argc, char** argv) {
Mat src = imread("E:/cats.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("image is empty!!!");
return -1;
}
namedWindow("src", WINDOW_AUTOSIZE);
imshow("src", src);
GaussianBlur(src, src, Size(3, 3), 0);
Mat gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);
ccl_stats_demo(binary);
waitKey(0);
destroyAllWindows();
return 0;
}
void ccl_stats_demo(Mat &image) {
Mat labels = Mat::zeros(image.size(), CV_32S);
Mat stats, centroids;
int num_labels = connectedComponentsWithStats(image, labels, stats,centroids,8, CV_32S, CCL_DEFAULT);
vector<Vec3b> colorTable(num_labels);
// backgound color
colorTable[0] = Vec3b(0, 0, 0);
for (int i = 1; i < num_labels; i++) {
colorTable[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
}
Mat result = Mat::zeros(image.size(), CV_8UC3);
int w = result.cols;
int h = result.rows;
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
int label = labels.at<int>(row, col);
result.at<Vec3b>(row, col) = colorTable[label];
}
}
for (int i = 1; i < num_labels; i++) {
//center
int cx = centroids.at<double>(i, 0);
int cy = centroids.at<double>(i, 1);
// rectangle and area
int x = stats.at<int>(i, CC_STAT_LEFT);
int y = stats.at<int>(i, CC_STAT_TOP);
int width = stats.at<int>(i, CC_STAT_WIDTH);
int height = stats.at<int>(i, CC_STAT_HEIGHT);
int area = stats.at<int>(i, CC_STAT_AREA);
// 绘制
Rect box(x, y, width, height);
rectangle(result, box, Scalar(0, 255, 0), 2, 8);
putText(result, format("%d", area), Point(x, y), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);
}
putText(result, format("number:%d", num_labels - 1), Point(10, 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);
printf("total labels : %d \n", (num_labels - 1));
imshow("CCL demo", result);
}