opencv中使用c++,对粘连轮廓使用分水岭,用面积筛选轮廓,对筛选后轮廓再椭圆拟合
时间: 2024-05-15 15:15:55 浏览: 136
以下是使用OpenCV C++实现的示例代码,其中包括了对粘连轮廓使用分水岭算法、对筛选后轮廓椭圆拟合等操作。
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main() {
Mat img = imread("test.png", 0); // 读取灰度图像
if (img.empty()) {
cerr << "Cannot read image file." << endl;
return -1;
}
// 二值化
Mat bw;
threshold(img, bw, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 寻找轮廓
vector<vector<Point>> contours;
findContours(bw, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 对轮廓进行面积筛选
vector<vector<Point>> filtered_contours;
for (size_t i = 0; i < contours.size(); i++) {
double area = contourArea(contours[i]);
if (area > 500) { // 设置面积阈值
filtered_contours.push_back(contours[i]);
}
}
// 对筛选后轮廓进行椭圆拟合
Mat result = Mat::zeros(img.size(), CV_8UC3);
for (size_t i = 0; i < filtered_contours.size(); i++) {
RotatedRect ellipse = fitEllipse(filtered_contours[i]);
drawContours(result, filtered_contours, i, Scalar(0, 255, 0), 2);
ellipse(result, ellipse, Scalar(0, 0, 255), 2);
}
// 显示结果
imshow("Result", result);
waitKey(0);
return 0;
}
```
对于粘连轮廓的分水岭分割,可以使用OpenCV提供的Watershed算法。具体实现步骤如下:
1. 对二值化图像进行距离变换,并计算其梯度。
2. 对梯度图像进行阈值分割,得到分水岭标记图像。
3. 对分水岭标记图像进行距离变换。
4. 将分水岭标记图像中的未知区域(即值为0的像素)赋值为距离变换图像中的最大值。
5. 对距离变换图像进行归一化,得到分水岭高度图像。
6. 对高度图像进行分水岭变换。
7. 对分水岭变换结果进行标记,并在原图像上进行颜色填充。
以下是使用OpenCV C++实现的示例代码:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main() {
Mat img = imread("test.png", 0); // 读取灰度图像
if (img.empty()) {
cerr << "Cannot read image file." << endl;
return -1;
}
// 二值化
Mat bw;
threshold(img, bw, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 距离变换
Mat dist;
distanceTransform(bw, dist, DIST_L2, 3);
// 计算梯度
Mat grad;
Sobel(dist, grad, CV_32F, 1, 1);
// 阈值分割
double minval, maxval;
minMaxLoc(grad, &minval, &maxval);
Mat markers;
threshold(grad, markers, 0.7 * maxval, 255, THRESH_BINARY);
// 分水岭变换
watershed(dist, markers);
// 标记区域
Mat result = Mat::zeros(img.size(), CV_8UC3);
for (int i = 0; i < markers.rows; i++) {
for (int j = 0; j < markers.cols; j++) {
int index = markers.at<int>(i, j);
if (index == -1) {
result.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
} else if (index > 0 && index <= 255) {
result.at<Vec3b>(i, j) = Vec3b(0, 0, index);
}
}
}
// 显示结果
imshow("Result", result);
waitKey(0);
return 0;
}
```
阅读全文