当前位置:   article > 正文

【6】python-opencv3教程:阈值分割(全阈值分割,局部阈值分割,直方图技术法,熵算法,自适应算法,Otsu算法)_opencv 局部阈值

opencv 局部阈值

第六节:阈值分割

一: 全阈值分割

 实例代码:

  1. image = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)
  2. the = 100 # 设置阈值为100
  3. maxval = 255
  4. dst, img = cv2.threshold(image, the, maxval, cv2.THRESH_BINARY)
  5. cv2.imshow('hand_thresh', img)
  6. cv2.waitKey(0)
  7. cv2.destroyAllWindows()

     给出你的阈值 ,然后告诉你的最大阈值是多少 。。。也就是你二值图中一个阈值为0,另外一个阈值可以指定为多少。。这里指定为255

  看一下输出结果。。

二:局部阈值分割

      局部阈值分割的核心是计算阈值矩阵。。比较常用的是后面提到的自适应阈值算法。。我们等会后面讲实现。。

三:直方图技术法

 

代码实现:

  1. import numpy as np
  2. import cv2
  3. def calcGrayHist(image):
  4. '''
  5. 统计像素值
  6. :param image:
  7. :return:
  8. '''
  9. # 灰度图像的高,宽
  10. rows, cols = image.shape
  11. # 存储灰度直方图
  12. grayHist = np.zeros([256], np.uint64)
  13. for r in range(rows):
  14. for c in range(cols):
  15. grayHist[image[r][c]] += 1
  16. return grayHist
  17. def threshTwoPeaks(image):
  18. # 计算灰度直方图
  19. histogram = calcGrayHist(image)
  20. # 找到灰度直方图的最大峰值对应的灰度值
  21. maxLoc = np.where(histogram == np.max(histogram))
  22. firstPeak = maxLoc[0][0]
  23. # 寻找灰度直方图的第二个峰值对应的灰度值
  24. measureDists = np.zeros([256], np.float32)
  25. for k in range(256):
  26. measureDists[k] = pow(k - firstPeak, 2)*histogram[k]
  27. maxLoc2 = np.where(measureDists == np.max(measureDists))
  28. secondPeak = maxLoc2[0][0]
  29. # 找两个峰值之间的最小值对应的灰度值,作为阈值
  30. thresh = 0
  31. if firstPeak > secondPeak:
  32. temp = histogram[int(secondPeak): int(firstPeak)]
  33. minLoc = np.where(temp == np.min(temp))
  34. thresh = secondPeak + minLoc[0][0] + 1
  35. else:
  36. temp = histogram[int(firstPeak): int(secondPeak)]
  37. minLoc = np.where(temp == np.min(temp))
  38. thresh = firstPeak + minLoc[0][0] + 1
  39. # 找到阈值,我们进行处理
  40. img = image.copy()
  41. img[img > thresh] = 255
  42. img[img <= thresh] = 0
  43. cv2.imshow('deal_image', img)
  44. cv2.waitKey(0)
  45. cv2.destroyAllWindows()
  46. if __name__ == '__main__':
  47. image = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)
  48. threshTwoPeaks(image)

输出结果:

四:熵算法

  

代码实现:

  1. import numpy as np
  2. import cv2
  3. import math
  4. def calcGrayHist(image):
  5. '''
  6. 统计像素值
  7. :param image:
  8. :return:
  9. '''
  10. # 灰度图像的高,宽
  11. rows, cols = image.shape
  12. # 存储灰度直方图
  13. grayHist = np.zeros([256], np.uint64)
  14. for r in range(rows):
  15. for c in range(cols):
  16. grayHist[image[r][c]] += 1
  17. return grayHist
  18. def threshEntroy(image):
  19. rows, cols = image.shape
  20. # 求灰度直方图
  21. grayHist = calcGrayHist(image)
  22. # 归一化灰度直方图,即概率直方图
  23. normGrayHist = grayHist / float(rows*cols)
  24. # 第一步:计算累加直方图,也称零阶累积矩
  25. zeroCumuMoment = np.zeros([256], np.float32)
  26. for k in range(256):
  27. if k == 0:
  28. zeroCumuMoment[k] = normGrayHist[k]
  29. else:
  30. zeroCumuMoment[k] = zeroCumuMoment[k-1] + normGrayHist[k]
  31. # 第二步:计算各个灰度级的熵
  32. entropy = np.zeros([256], np.float32)
  33. for k in range(256):
  34. if k == 0:
  35. if normGrayHist[k] == 0:
  36. entropy[k] = 0
  37. else:
  38. entropy[k] = -normGrayHist[k]*math.log10(normGrayHist[k])
  39. else:
  40. if normGrayHist[k] == 0:
  41. entropy[k] = entropy[k-1]
  42. else:
  43. entropy[k] = entropy[k-1] - normGrayHist[k]*math.log10(normGrayHist[k])
  44. # 第三步:找阈值
  45. fT = np.zeros([256], np.float32)
  46. ft1, ft2 = 0.0, 0.0
  47. totalEntropy = entropy[255]
  48. for k in range(255):
  49. # 找最大值
  50. maxFront = np.max(normGrayHist[0: k+1])
  51. maxBack = np.max(normGrayHist[k+1: 256])
  52. if (maxFront == 0 or zeroCumuMoment[k] == 0
  53. or maxFront == 1 or zeroCumuMoment[k] == 1 or totalEntropy == 0):
  54. ft1 = 0
  55. else:
  56. ft1 = entropy[k] / totalEntropy*(math.log10(zeroCumuMoment[k])/math.log10(maxFront))
  57. if (maxBack == 0 or 1-zeroCumuMoment[k] == 0
  58. or maxBack == 1 or 1-zeroCumuMoment[k] == 1):
  59. ft2 = 0
  60. else:
  61. if totalEntropy == 0:
  62. ft2 = (math.log10(1-zeroCumuMoment[k]) / math.log10(maxBack))
  63. else:
  64. ft2 = (1-entropy[k]/totalEntropy)*(math.log10(1-zeroCumuMoment[k])/math.log10(maxBack))
  65. fT[k] = ft1 + ft2
  66. # 找最大值的索引,作为得到的阈值
  67. threshLoc = np.where(fT == np.max(fT))
  68. thresh = threshLoc[0][0]
  69. # 阈值处理
  70. threshold = np.copy(image)
  71. threshold[threshold > thresh] = 255
  72. threshold[threshold <= thresh] = 0
  73. return threshold
  74. if __name__ == '__main__':
  75. image = cv2.imread('img5.jpg', cv2.IMREAD_GRAYSCALE)
  76. img = threshEntroy(image)
  77. cv2.imshow('origin', image)
  78. cv2.imshow('deal_image', img)
  79. cv2.waitKey(0)
  80. cv2.destroyAllWindows()

输出结果:

五:Otsu算法

这里就不具体实现了。。我们调用opencv给的API

  1. image = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)
  2. maxval = 255
  3. otsuThe = 0
  4. otsuThe, dst_Otsu = cv2.threshold(image, otsuThe, maxval, cv2.THRESH_OTSU)
  5. cv2.imshow('Otsu', dst_Otsu)
  6. cv2.waitKey(0)
  7. cv2.destroyAllWindows()

输出结果:

 六:自适应阈值算法

 

代码实现:

  1. import cv2
  2. import numpy as np
  3. def adaptiveThresh(I, winSize, ratio=0.15):
  4. # 第一步:对图像矩阵进行均值平滑
  5. I_mean = cv2.boxFilter(I, cv2.CV_32FC1, winSize)
  6. # 第二步:原图像矩阵与平滑结果做差
  7. out = I - (1.0 - ratio) * I_mean
  8. # 第三步:当差值大于或等于0时,输出值为255;反之,输出值为0
  9. out[out >= 0] = 255
  10. out[out < 0] = 0
  11. out = out.astype(np.uint8)
  12. return out
  13. if __name__ == '__main__':
  14. image = cv2.imread('img7.jpg', cv2.IMREAD_GRAYSCALE)
  15. img = adaptiveThresh(image, (5, 5))
  16. cv2.imshow('origin', image)
  17. cv2.imshow('deal_image', img)
  18. cv2.waitKey(0)
  19. cv2.destroyAllWindows()

结果展示:
 

 

      未完待续。。。。。。

                                      下节你将能够学到一些形态学处理(腐蚀,膨胀等等)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/379577
推荐阅读
相关标签
  

闽ICP备14008679号