Opencv之图像分割思路及代码实现

11 篇文章 0 订阅

实现思路:

1、首先对图像进行预处理,包括对图像进行高斯滤波、边缘检测和二值化等操作;

2、使用分水岭算法对图像进行分割,它将图片分割成不同的区域;

3、最后,根据分割后的区域,我们可以绘制出属于不同区域的轮廓,并将其作为分割图像的结果。

C/C++代码实现:

#include <opencv2/opencv.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;
 
// 预处理:高斯滤波+边缘检测+二值化
Mat preprocess(Mat& img)
{
    Mat blur,edge,thresh;
    GaussianBlur(img, blur, Size(9, 9), 0);
    Canny(blur, edge, 30, 150);
    threshold(edge, thresh, 127, 255, 0);
    return thresh;
}
 
// 分水岭算法分割
Mat segmentation(Mat& img)
{
    Mat markers = Mat::zeros(img.size(), CV_8U);
    markers(Rect(1, 1, img.cols - 2, img.rows - 2)) = 255;
    WatershedSegmenter segmenter;
    segmenter.setMarkers(markers);
    segmenter.process(img);
    return segmenter.getSegmentation();
}
 
// 绘制轮廓
void drawContour(Mat& img, Mat& segImg)
{
    Mat img_color;
    cvtColor(img, img_color, COLOR_GRAY2BGR);
    vector<vector<Point>> contours;
    findContours(segImg, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
    drawContours(img_color, contours, -1, Scalar(0, 0, 255), 3);
    imshow("result", img_color);
}
 
int main(int argc, char** argv)
{
    Mat img = imread("image.jpg", 0);
    if (img.empty())
    {
        cout << "Could not open or find the image!\n" << endl;
        return -1;
    }
    imshow("input", img);
 
    Mat thresh = preprocess(img);
 
    Mat segImg = segmentation(thresh);
 
    drawContour(img, segImg);
    imwrite("result.jpg", segImg);
 
    waitKey(0);
    return 0;
}
抱歉,OpenCVSharp并不直接支持"滴水算法"(也称为区域生长),这是一个基于图像处理和像素连接的经典计算机视觉技术,通常用于分割图像。OpenCVSharp是C#编写的OpenCV接口库,它主要用于与原生OpenCV库交互,而不是直接提供完整的算法实现。 然而,你可以使用OpenCVSharp来实现滴水算法的一些基本步骤,如阈值化、腐蚀膨胀、区域生长等。下面是一个简单的示例,展示了如何使用OpenCVSharp进行二值图像的区域生长: ```csharp using Emgu.CV; using Emgu.CV.Structure; // 假设img是已经处理过的灰度图像 Mat src = new Mat("image.jpg", ImreadModes.GrayScale); // 转换成8位单通道图像 Mat gray = src.Clone(); gray.CvtColor(Color.Bgr2Gray, ColorConversionCodes.Bgr2Gray); // 应用阈值以创建二值图像 double thresholdValue = 128; // 根据图像调整这个值 Mat binaryImage = new Mat(); threshold(gray, binaryImage, thresholdValue, 255, ThresholdType.Binary); // 初始化种子点(通常是前景像素) Point seedPoint = new Point(10, 10); bool[] visited = new bool[src.Rows * src.Cols]; // 区域生长函数(这里简化,仅展示基本思路) void RegionGrowth(Point seed, Mat& image) { // 从种子开始 visited[seed.Y * src.Cols + seed.X] = true; // 检查相邻像素 for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) { if (y == 0 && x == 0) continue; // 忽略自身 Point pixel = new Point(seed.X + x, seed.Y + y); if (pixel.X >= 0 && pixel.X < src.Cols && pixel.Y >= 0 && pixel.Y < src.Rows && image.At<byte>(pixel) != 0 && !visited[pixel.Y * src.Cols + pixel.X]) { visited[pixel.Y * src.Cols + pixel.X] = true; // 对这些像素应用相同的操作(比如染色) } } } // 运行区域生长 RegionGrowth(seedPoint, binaryImage); // 显示结果 binaryImage.Show(); ``` 请注意,这只是一个基础示例,实际应用中可能需要更复杂的条件判断和优化。你可以在网上找到更详细的滴水算法教程来进一步学习。如果你想要使用OpenCVSharp的高级功能,建议查阅官方文档或社区资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金戈鐡馬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值