图像二值化代码实现

图像二值化代码实现

  • 固定阈值二值化
  • Otsu 阈值二值化
  • 自适应阈值二值化

固定阈值二值化

opencv实现:

ret, th = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('opencv', th)

python实现:

thresh = 127
new_img = np.zeros((h,w),np.uint8)
for i in range(h):
    for j in range(w):
        if gray[i,j]>thresh:
            new_img[i,j] = 255
        else:
            new_img[i, j] = 0
cv2.imshow("threshold",new_img)

图像二值化代码实现_第1张图片

Otsu 阈值二值化

日本人Nobuyuki Otsu (大津展之)发明,故名大津法、Otsu法,其实是一种最大类间方差法。
图像二值化代码实现_第2张图片
opencv实现:

ret, th = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow('opencv', th)

python实现:

h,w = img.shape[:2]
sum = h*w

#统计各灰度级数量
histogram = np.zeros(256, np.int32)
for i in range(h):
    for j in range(w):
        p = gray[i,j]
        histogram[p] +=1

#统计各灰度级所占比例
probability = np.zeros(256, np.float32)
for i in range(256):
    probability[i] = histogram[i]/sum

#计算平均灰度值
ma = 0
for i in range(256):
    ma += i*probability[i]

maxcov = 0
maxthresh = 0
#统计前景和背景的平均灰度值
for i in range(1, 255):
    p1,p2 = 0,0 #前景和背景灰度概率
    mk = 0  #灰度级总和
    for j in range(i):
        p1 += probability[j]
        mk += j*probability[j]
    m1 = mk/p1
    p2 = 1 - p1
    m2 = (ma-mk)/p2

    #计算类间方差
    cov = p1*p2*(m1-m2)**2
    if cov>maxcov:
        maxcov = cov
        maxthresh = i

print(maxthresh)
new_img = np.zeros((h,w),np.uint8)
for i in range(h):
    for j in range(w):
        if gray[i,j]>maxthresh:
            new_img[i,j] = 255
        else:
            new_img[i, j] = 0

cv2.imshow("otsu",new_img)

图像二值化代码实现_第3张图片

自适应阈值二值化

自适应阈值二值化会每次取图片的一个区域计算阈值,针对不同区域设置不同阈值,该方法主要为了应对在不同的光照条件下导致的差异。

opencv两种实现:
cv2.ADAPTIVE_THRESH_MEAN_C:阈值取邻域的平均值
cv2.ADAPTIVE_THRESH_GAUSSIAN_C:阈值取邻域值的加权和,权重是高斯核

参数1:原图
参数2:最大阈值,一般为255
参数3:小区域阈值的两种计算方式
参数4:阈值的方式(5种)
参数5:小区域的面积
参数6:最终阈值为小区域计算出的阈值再减去此值

th=cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
# th=cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
cv2.imshow('opencv', th)

图像二值化代码实现_第4张图片
python实现:

#计算积分图
integralimage = cv2.integral(gray_image, cv2.CV_32F)
width = gray_image.shape[1]
height = gray_image.shape[0]
win_length = 5
image_thresh = np.zeros((height, width, 1), dtype=np.uint8)

for j in range(height):
   for i in range(width):
       x1 = i - win_length
       x2 = i + win_length
       y1 = j - win_length
       y2 = j + win_length

       #check the border
       if (x1 < 0):
           x1 = 0
       if (y1 < 0):
           y1 = 0
       if (x2 > width):
           x2 = width - 1
       if (y2 > height):
           y2 = height - 1
       count = (x2 - x1) * (y2 - y1)

       sum = integralimage[y2, x2] - integralimage[y1, x2] - integralimage[y2, x1] + integralimage[y1, x1]
       if gray_image[j, i] < sum/count:
           image_thresh[j, i] = 0
       else:
           image_thresh[j, i] = 255

图像二值化代码实现_第5张图片

你可能感兴趣的:(图像处理)