Python+OpenCV大津法源代码编写

OTSU算法是由日本学者大津于1979年提出的一种对图像进行二值化的高效算法。具体原理优快云上一大堆,在此不再赘述,直接上自己写的源代码之前先说一下本人的算法步骤:
(1)读入一幅图像;
(2)将读入的图像灰度化;
(3)将灰度图中各灰度级个数进行统计;
(4)统计各灰度级个数占图像的比例;
(5)遍历灰度级,根据公式求最大类间方差;
(6)最大类间方差对应的灰度级即为阈值,根据阈值对图像进行二值化划分。

Python+OpenCV代码如下:

import cv2 as cv
import numpy as np

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:
                otsuimg[i,j]=255
            else:
                otsuimg[i,j]=0
    return otsuimg

image = cv.imread("D:/selina.png")
grayimage = rgb2gray(image)
otsuimage = otsu(grayimage)
cv.imshow("image", image)
cv.imshow("grayimage",grayimage)
cv.imshow("otsu", otsuimage)
cv.waitKey(0)
cv.destroyAllWindows()

实验结果:

在这里插入图片描述
以上就是大津法全过程,也算是数字图像处理中的基础算法之一,有关大津法的改进优快云上也有好多,本人实现的也只是最基本的。

### 如何使用OpenCV进行轮廓检测和提取 #### 准备工作 为了能够顺利执行轮廓检测操作,在Python环境中需先安装`opencv-python`库。可以通过pip工具来完成这一过程。 ```bash pip install opencv-python ``` #### 加载并预处理图像 在进行轮廓检测之前,通常需要对输入图片做一定的预处理以便获得更好的效果。这可能涉及到灰度化、二值化以及噪声去除等步骤[^2]。 ```python import cv2 import numpy as np # 读取原始彩色图象 image = cv2.imread('example.jpg') # 将其转换成灰度模式 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 应用高斯模糊减少噪音干扰 blurred_gray_image = cv2.GaussianBlur(gray_image, (5, 5), 0) # 利用大津(Otsu's method)自动计算阈值来进行二值化处理 _, binary_image = cv2.threshold(blurred_gray_image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) ``` #### 执行轮廓查找 一旦完成了上述准备工作之后就可以调用`findContours()`函数获取目标对象的外接多边形表示形式即所谓的“轮廓”。需要注意的是该版本返回三个参数分别为修改后的源图像(一般不需要关注),所有发现的轮廓列表及其层次结构信息;而在较新的API定义下只保留了两个输出项——后者被移除了[^1]。 ```python contours, _ = cv2.findContours(binary_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ``` 这里选择了`cv2.RETR_EXTERNAL`作为检索模式意味着仅考虑最外面一层轮廓而忽略内部嵌套情况;对于近似算法则选用了`cv2.CHAIN_APPROX_SIMPLE`选项尽可能简化最终结果集中的点数从而提高效率[^3]。 #### 绘制轮廓 最后一步就是把找到的所有轮廓绘制回原图之上用于可视化展示目的: ```python output_with_contours = image.copy() for contour in contours: area = cv2.contourArea(contour) if area > 100: # 过滤掉面积过小的对象 color = (np.random.randint(0, 256), np.random.randint(0, 256), np.random.randint(0, 256)) # 填充当前轮廓区域 cv2.drawContours(output_with_contours, [contour], -1, color, thickness=cv2.FILLED) # 显示带有标注的结果图 cv2.imshow("Detected Contours", output_with_contours) cv2.waitKey(0) cv2.destroyAllWindows() ``` 通过以上代码片段可以看到整个流程涵盖了从加载到显示各个阶段的操作细节说明。当然实际应用当中还可以根据具体需求调整相应参数设置以达到更理想的效果。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值