圖像二值化也叫做圖像閾值化處理,通過設定某個閾值爲門限,把多灰度級的圖像轉化爲僅僅有兩個極端的灰度級(0和255)。
閾值全局固定
利用python實現閾值全局固定時的二值化
import cv2
import matplotlib.pyplot as plt
import numpy as np
import math
import os
import pandas as pd
from tqdm import tqdm
image = cv2.imread("peng.png",0)
h = image.shape[0]
w = image.shape[1]
## 唯一確定閾值
a = 150
new_image = np.zeros((h,w),np.uint8)
for i in tqdm(range(h)):
for j in range(w):
if(image[i,j]> a ):
new_image[i,j] = 255
else:
new_image[i,j] = 0
print(new_image)
cv2.imshow("new",new_image)
cv2.waitKey()
效果圖
大津法OTSU
- 大津法又叫最大類間方差法、最大類間閾值法(OTSU)。
- 它的基本思想是,用一個閾值將圖像中的數據分爲兩類,一類中圖像的像素點的灰度均小於這個閾值,另一類中的圖像的像素點的灰度均大於或者等於該閾值。如果這兩個類中像素點的灰度的方差越大,說明獲取到的閾值就是最佳的閾值。
- 則利用該閾值可以將圖像分爲前景和背景兩個部分。而我們所感興趣的部分一般爲前景。
公式流程可自行百度。。。
利用Python實現大津法
import cv2
import os
import numpy as np
import pandas as pd
from tqdm import tqdm
### 首先將圖片轉化爲灰度圖像
image = cv2.imread("peng.png")
def rgb2gray(image):
h = image.shape[0]
w = image.shape[1]
grayimage = np.zeros((h,w),np.uint8)
for i in tqdm(range(h)):
for j in range(w):
grayimage [i,j] = 0.144*image[i,j,0]+0.587*image[i,j,1]+0.299*image[i,j,1]
return grayimage
### 大津法
def otsu(image):
### 高和寬
h = image.shape[0]
w = image.shape[1]
### 求總像素
m = h*w
otsuimg = np.zeros((h, w), np.uint8)
##初始閾值
initial_threshold = 0
### 最終閾值
final_threshold = 0
# 初始化各灰度級個數統計參數
histogram = np.zeros(256, np.int32)
# 初始化各灰度級佔圖像中的分佈的統計參數
probability = np.zeros(256, np.float32)
### 各個灰度級的個數統計
for i in tqdm(range(h)):
for j in range(w):
s = image[i,j]
histogram[s] = histogram[s] +1
### 各灰度級佔圖像中的分佈的統計參數
for i in tqdm(range(256)):
probability[i] = histogram[i]/m
for i in tqdm(range(255)):
w0 = w1 = 0 ## 前景和背景的灰度數
fgs = bgs = 0 # 定義前景像素點灰度級總和背景像素點灰度級總和
for j in range(256):
if j <= i: # 當前i爲分割閾值
w0 += probability[j] # 前景像素點佔整幅圖像的比例累加
fgs += j * probability[j]
else:
w1 += probability[j] # 背景像素點佔整幅圖像的比例累加
bgs += j * probability[j]
u0 = fgs / w0 # 前景像素點的平均灰度
u1 = bgs / w1 # 背景像素點的平均灰度
G = w0*w1*(u0-u1)**2
if G >= initial_threshold:
initial_threshold = G
final_threshold = i
print(final_threshold)
for i in range(h):
for j in range(w):
if image[i, j] > final_threshold:
otsuimg[i, j] = 255
else:
otsuimg[i, j] = 0
return otsuimg
grayimage = rgb2gray(image)
otsuimage = otsu(grayimage)
cv2.imshow("grayimage",grayimage)
cv2.imshow("otsuimage",otsuimage)
cv2.waitKey()
# print(new_image)