• python opencv之图像分割、计算面积


    以下代码是一个基于K-means聚类算法进行图像分割的实现。通过读取一个彩色图像,将其转化为二维数组形式。然后使用K-means算法对像素点进行聚类,聚类个数为7。根据聚类后的标签值对像素点进行着色,并创建掩膜图像。接着使用形态学开运算和闭运算去掉周围的绿色点和填充区域内部空隙,找到最大的轮廓并计算其面积。最后再将最大轮廓绘制在原始图像上并显示出来。

    1. import cv2
    2. import numpy as np
    3. # 读取彩色图像
    4. img = cv2.imread(r'C:\Users\Pictures\rm.png')
    5. # 将图像数据转换为二维数组形式
    6. values = img.reshape((-1, 3))
    7. values = np.float32(values)
    8. # K-Means聚类
    9. K = 7
    10. criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    11. ret, label, center = cv2.kmeans(values, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
    12. # 创建新图像并根据聚类标签对像素点着色
    13. segmented_img = np.zeros_like(values)
    14. # segmented_img[np.where(label==0)[0], :] = [255, 0, 0] # 给第0类像素点赋值蓝色
    15. segmented_img[np.where(label==1)[0], :] = [0, 255, 0] # 给第1类像素点赋值绿色
    16. # segmented_img[np.where(label==2)[0], :] = [0, 0, 255] # 给第2类像素点赋值红色
    17. # segmented_img[np.where(label==3)[0], :] = [0, 0, 0] # 给第3类像素点赋值黑色
    18. # segmented_img[np.where(label==4)[0], :] = [255, 255, 255] # 给第3类像素点赋值白色
    19. # 将分割后图像重新转化成与原图像相同的维度
    20. segmented_img = segmented_img.reshape(img.shape)
    21. # 创建掩膜图像
    22. mask = np.zeros(segmented_img.shape[:2], dtype=np.uint8)
    23. mask[np.where(np.all(segmented_img == [0, 255, 0], axis=-1))] = 255
    24. # 进行形态学开运算,去掉周围的绿色点
    25. kernel = np.ones((5,5),np.uint8)
    26. opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    27. # 进行形态学闭运算,填充区域内部空隙
    28. closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
    29. # 找到轮廓并获取最大轮廓及其面积
    30. contours, _ = cv2.findContours(closing, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    31. # max_contour = max(contours, key=cv2.contourArea)
    32. total_area = 0
    33. for i, contour in enumerate(contours):
    34. # 计算轮廓面积
    35. area = cv2.contourArea(contour)
    36. total_area += area
    37. # 绘制最大轮廓并显示在原图上
    38. output = img.copy()
    39. cv2.drawContours(output, contours, -1, (0, 255, 0), 2)
    40. cv2.imshow('Contour', output)
    41. # 显示聚类结果
    42. cv2.imshow('Image', img)
    43. cv2.imshow('Segmented Image', segmented_img)
    44. cv2.imshow('Mask', closing)
    45. # 等待关闭窗口
    46. cv2.waitKey(0)
    47. cv2.destroyAllWindows()

    图片

    图片

    图片

    图片

    几个问题,供读者思考:

    1. 为什么选择K-means聚类算法?

    2. 为什么是聚7类?

    3. 这种方法具有通用性吗,换其他类似图片也提取准确吗?

    4. 还有更好的方法吗,如果目标的轮廓更加复杂,该怎么处理?

    5. 已经算出了图上面积,怎么计算实际面积?

  • 相关阅读:
    g++模板显式实例化big file例子
    Proxmox VE 近期有ARM 版本发布么?
    C++课堂整理--第一章内容
    飞天使-django创建一个初始项目过程
    面试整理(不断更新)
    jenkins集成maven环境
    JVM 类加载器子系统
    python神经网络编程 豆瓣,神经网络算法python代码
    园区组网配置实例
    Python Flask Web教程:make_response的详细用法
  • 原文地址:https://blog.csdn.net/T20151470/article/details/134098063