def rgb2gray(img): h=img.shape[0] w=img.shape[1] img1=np.zeros((h,w),np.uint8) for i in range(h): for j in range(w): img1[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,1] return img1 def otsu(img): h=img.shape[0] w=img.shape[1] m=h*w # 图像像素点总和 otsuimg=np.zeros((h,w),np.uint8) threshold_max=threshold=0 # 定义临时阈值和最终阈值 histogram=np.zeros(256,np.int32) # 初始化各灰度级个数统计参数 probability=np.zeros(256,np.float32) # 初始化各灰度级占图像中的分布的统计参数 for i in range (h): for j in range (w): s=img[i,j] histogram[s]+=1 # 统计像素中每个灰度级在整幅图像中的个数 for k in range (256): probability[k]=histogram[k]/m # 统计每个灰度级个数占图像中的比例 for i in range (255): w0 = w1 = 0 # 定义前景像素点和背景像素点灰度级占图像中的分布 fgs = bgs = 0 # 定义前景像素点灰度级总和and背景像素点灰度级总和 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>=threshold_max: threshold_max=g threshold=i print(threshold) for i in range (h): for j in range (w): if img[i,j]>threshold-3: otsuimg[i,j]=255 else: otsuimg[i,j]=0 return otsuimg image = cv.imread(r"C:/Users/zhou/Desktop/oil meter/images/2_2021.jpg") grayimage = rgb2gray(image) otsuimage = otsu(grayimage) cv.imshow("image", image) cv.imshow("grayimage",grayimage) cv.imshow("otsu", otsuimage) cv.waitKey(0) cv.destroyAllWindows()