ZBLOG

opencv C++ 图像分割

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

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

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

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. int main() {
  4. // 读取图像
  5. cv::Mat image = cv::imread("path_to_image.jpg");
  6. if (image.empty()) {
  7. std::cerr << "Error: Unable to load image!" << std::endl;
  8. return -1;
  9. }
  10. // 转换为灰度图
  11. cv::Mat gray;
  12. cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
  13. // 应用阈值
  14. cv::Mat binary;
  15. double thresh = 128; // 阈值
  16. cv::threshold(gray, binary, thresh, 255, cv::THRESH_BINARY);
  17. // 显示结果
  18. cv::imshow("Original Image", image);
  19. cv::imshow("Binary Image", binary);
  20. cv::waitKey(0);
  21. return 0;
  22. }

示例 2:轮廓检测

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

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. int main() {
  4. // 读取图像
  5. cv::Mat image = cv::imread("path_to_image.jpg");
  6. if (image.empty()) {
  7. std::cerr << "Error: Unable to load image!" << std::endl;
  8. return -1;
  9. }
  10. // 转换为灰度图并应用高斯模糊
  11. cv::Mat gray, blurred;
  12. cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
  13. cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0);
  14. // 应用Canny边缘检测
  15. cv::Mat edges;
  16. cv::Canny(blurred, edges, 50, 150);
  17. // 找到轮廓
  18. std::vector<std::vector<cv::Point>> contours;
  19. std::vector<cv::Vec4i> hierarchy;
  20. cv::findContours(edges.clone(), contours, hierarchy,
  21. cv::RETR_EXTERNAL ,cv ::CHAIN_APPROX_SIMPLE );
  22. // 在原始图上绘制轮廓
  23. for (size_t i = 0; i < contours.size(); i++) {
  24. drawContours(image, contours, static_cast<int>(i),
  25. CV_RGB(0,255 ,0), 2);
  26. }
  27. // 显示结果
  28. imshow("Contours", image);
  29. waitKey(0);
  30. return 0;
  31. }

示例 3:K-means 聚类

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

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. int main() {
  4. // 读取图像
  5. cv :: Mat image =cv :: imread ("path_to_image.jpg");
  6. if (image.empty()) {
  7. std :: cerr <<"Error: Unable to load image!"<<std :: endl ;
  8. return-1 ;
  9. }
  10. // 将数据转换为适合K-means算法格式,即二维矩阵(每个点都有三通道)
  11. cv :: Mat data =image.reshape (1,image.total());
  12. data.convertTo(data,CV_32F);
  13. // 定义K-means参数
  14. int K=3;
  15. cv :: Mat labels ;
  16. cv :: Mat centers ;
  17. cv :: kmeans(data,K ,labels,
  18. {cv :: TermCriteria(cv :: TERM_CRITERIA_EPS +cv ::
  19. TERM_CRITERIA_MAX_ITER ,10 ,1.0),
  20. KMEANS_RANDOM_CENTERS},10 ,centers);
  21. // 重构分割后的图像
  22. for(int i=0;i<data.rows ;i++)
  23. 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;
  24. image=data.reshape (3,image.rows );
  25. image.convertTo(image,CV_8UC3);
  26. imshow ("K-Means Segmentation",image );
  27. waitKey (0);
  28. return(0);
  29. }

编译与运行:

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

  1. 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

注册

已经有帐号?