ZBLOG

opencv C++ 图像分割

在 OpenCV 中,图像分割是一个常见的操作,可以通过多种方法实现。以下是几种常用的图像分割技术示例,包括基于阈值的方法、轮廓检测和使用 K-means 聚类进行分割。

示例 1:基于阈值的图像分割

这是最简单且常用的图像分割方法之一。

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("path_to_image.jpg");
    if (image.empty()) {
        std::cerr << "Error: Unable to load image!" << std::endl;
        return -1;
    }

    // 转换为灰度图
    cv::Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);

    // 应用阈值
    cv::Mat binary;
    double thresh = 128; // 阈值
    cv::threshold(gray, binary, thresh, 255, cv::THRESH_BINARY);

    // 显示结果
    cv::imshow("Original Image", image);
    cv::imshow("Binary Image", binary);

    cv::waitKey(0);
    
    return 0;
}

示例 2:轮廓检测

通过找到物体的边缘并提取轮廓来进行分割。

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("path_to_image.jpg");
    if (image.empty()) {
        std::cerr << "Error: Unable to load image!" << std::endl;
        return -1;
    }

    // 转换为灰度图并应用高斯模糊
    cv::Mat gray, blurred;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
    cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0);

   // 应用Canny边缘检测
   cv::Mat edges;
   cv::Canny(blurred, edges, 50, 150);

   // 找到轮廓
   std::vector<std::vector<cv::Point>> contours;
   std::vector<cv::Vec4i> hierarchy;

   cv::findContours(edges.clone(), contours, hierarchy, 
                    cv::RETR_EXTERNAL ,cv ::CHAIN_APPROX_SIMPLE );

   // 在原始图上绘制轮廓
   for (size_t i = 0; i < contours.size(); i++) {
       drawContours(image, contours, static_cast<int>(i), 
                    CV_RGB(0,255 ,0), 2); 
   }
   
   // 显示结果
   imshow("Contours", image);
   
   waitKey(0);
   
return 0;

}

示例 3:K-means 聚类

使用 K-means 算法进行颜色空间的聚类以实现图像分割。

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    	cv :: Mat image =cv :: imread ("path_to_image.jpg");
	if (image.empty()) {
		std :: cerr <<"Error: Unable to load image!"<<std :: endl ;
		return-1 ;
	}

	// 将数据转换为适合K-means算法格式,即二维矩阵(每个点都有三通道)
	cv :: Mat data =image.reshape (1,image.total());
	data.convertTo(data,CV_32F); 

	// 定义K-means参数
	int K=3; 
	cv :: Mat labels ;
	cv :: Mat centers ;
	cv :: kmeans(data,K ,labels,
		         {cv :: TermCriteria(cv :: TERM_CRITERIA_EPS +cv ::
		         TERM_CRITERIA_MAX_ITER ,10 ,1.0),
                 	KMEANS_RANDOM_CENTERS},10 ,centers);

	// 重构分割后的图像 
	for(int i=0;i<data.rows ;i++)
	    data.at<float>(i)=(centers.at<float>(labels.at<int>(i),0)+centers.at<float>(labels.at<int>(i),1)+centers.at<float>(labels.at<int>(i),2))/3;

	image=data.reshape (3,image.rows ); 
	image.convertTo(image,CV_8UC3); 

	imshow ("K-Means Segmentation",image ); 
	waitKey (0); 

	return(0);	
}

编译与运行:

确保你已经安装了 OpenCV,并正确设置了编译环境。可以使用 g++ 或其他 C++ 编译器编译这些代码。例如:

g++ -o segmentation_example your_code.cpp `pkg-config --cflags --libs opencv4`

请根据你的系统和 OpenCV 安装情况调整命令。如果想要运行某个特定示例,请将相关代码放入同一文件中或按需创建多个文件。然后,替换 "path_to_image.jpg" 为实际的图片路径,以便程序能正常读取该文件。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=19404

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?