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)
日本人Nobuyuki Otsu (大津展之)发明,故名大津法、Otsu法,其实是一种最大类间方差法。
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)
自适应阈值二值化会每次取图片的一个区域计算阈值,针对不同区域设置不同阈值,该方法主要为了应对在不同的光照条件下导致的差异。
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)
#计算积分图
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