首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐
2025年5月15日 星期四 1:25am

opencv进阶学习9:图像阈值大全,图像二值化,超大图像二值化

  • 23-09-22 21:02
  • 3744
  • 13014
blog.csdn.net

基础版笔记链接:
python3+opencv学习笔记汇总目录(适合基础入门学习)
进阶版笔记目录链接:
python+opencv进阶版学习笔记目录(适合有一定基础)

基础版二值化讲解
opencv学习笔记10:阈值分割

图像二值化原理

二值化方法:全局阈值,局部阈值
具体原理见上面链接

图像二值化实现

1.全局阈值
通常情况,我们一般不知道设定怎样的阈值thresh才能得到比较好的二值化效果,只能去试。如对于一幅双峰图像(理解为图像直方图中存在两个峰),我们指定的阈值应尽量在两个峰之间的峰谷。这时,就可以用第四个参数THRESH_OTSU,它对一幅双峰图像自动根据其直方图计算出合适的阈值(对于非双峰图,这种方法得到的结果可能不理想)。

对于双峰图,我们需要多传入一个参数cv2.THRESH_OTSU,并且把阈值thresh设为0,设置为其他数也默认为0,算法会找到最优阈值,并作为第一个返回值ret返回。

cv2.THRESH_BINARY:二进制阈值。把亮的处理成白色,暗的处理成黑色

cv2.THRESH_BINARY_INV:反二进制阈值。把亮的处理成黑色,暗的处理成白色
cv2.THRESH_TRUNC:截断阈值。亮的不能太亮,有上限,暗的不变
cv2.THRESH_TOZERO_INV:threshold 反阈值化为0,把比较亮的部分处理成0成黑色,小于等于阈值的像素点不变
cv2.THRESH_TOZERO:threshold 阈值化为0,比较亮的部分不变,比较暗的部分处理成黑色为0

import cv2 as cv
import numpy as np

def threshold_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY|cv.THRESH_OTSU)
    print("threshold value %s"%ret)
    cv.imshow("binary", binary)

print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("duoren.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
threshold_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

图像直方图

该图没有明显两个波峰,将就用

结果

二进制阈值

修改cv.THRESH_BINARY为其他参数。结果如下

cv2.THRESH_BINARY_INV:反二进制阈值

cv2.THRESH_TRUNC:截断阈值

cv2.THRESH_TOZERO_INV: 反阈值化为0

cv2.THRESH_TOZERO:阈值化为0

2.局部阈值 自适应阈值
cv2.adaptiveThreshold()

ADAPTIVE_THRESH_MEAN_C :把图像分成一个个小的区域,每个区域做阈值处理,每个区域阈值为这个区域的均值减去常量c,大于阈值取白色,小于取黑色。整个图像有很多阈值。

ADAPTIVE_THRESH_GAUSSIAN_C:把图像分成一个个小的区域,阈值是每个区域均值的权重和(均值分布为高斯分布,越接近中心均值权重越高)再减去常量c,整个图像只有一个阈值
blocksize:区域大小,必须是奇数。
C: 二值化时,如何一个像素点减去均值大于C,才把这个点设为白色,能减弱噪声影响。等于说阈值=均值-C

在这里插入图片描述

import cv2 as cv
import numpy as np


def local_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
    cv.imshow("binary", binary)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("duoren.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
local_threshold(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

换一张经典图
自适应阈值结果

全局阈值结果

首先还是自适应阈值吧。

3.自定义阈值
自己实现一个二值化处理

import cv2 as cv
import numpy as np

def custom_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)#转换为灰度图
    h, w = gray.shape[:2]#高宽
    m = np.reshape(gray, [1, w*h])#将图像转换为1维数组,1行多列
    mean = m.sum() / (w*h)#求均值,把均值作为阈值
    print("mean : ", mean)
    ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
    cv.imshow("binary", binary)

print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("duoren.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
custom_threshold(src)
cv.waitKey(0)
cv.destroyAllWindows()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

超大图像二值化

方法:图像分块,再分别阈值
图超大时,由于光照不能很好分布全图,所以有很多噪声。

import cv2 as cv
import numpy as np

def big_image_binary(image):
    print(image.shape)#(1200, 1920, 3)
    cw = 256#每个小块宽
    ch = 256#每个小块高
    h, w = image.shape[:2]#整个图像高,宽
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)#转灰度图
    for row in range(0, h, ch):#遍历每一小块高
        for col in range(0, w, cw):#遍历每一块宽
            roi = gray[row:row+ch, col:cw+col]#小块区域
            #print(np.std(roi), np.mean(roi))#打印小块方差,均值
            dev = np.std(roi)
            if dev < 15:
                gray[row:row + ch, col:cw + col] = 255#去除空白区域的噪点
            else:
                #全局阈值
                ret, dst = cv.threshold(roi, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)#cv.THRESH_OTSU自动寻找阈值
                #自适应阈值
                #dst = cv.adaptiveThreshold(roi, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
                gray[row:row + ch, col:cw + col] = dst#在原图上替换小块二值化结果
    #cv.imwrite("result_binary.png", gray)
    cv.imshow('result_binary',gray)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("limi.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
big_image_binary(src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

说明
下面代码是去除图像空白小块区域噪声。如果一个小块没有其他东西,那么它的方差就很小,去除一些小黑点(去噪)

if dev < 15:
                gray[row:row + ch, col:cw + col] = 255#去除空白区域的噪点
  • 1
  • 2

电气专业的计算机萌新,写博文不容易。如果你觉得本文对你有用,请点个赞支持下。谢谢。

文章知识点与官方知识档案匹配,可进一步学习相关知识
OpenCV技能树进阶任务OpenCV问答20473 人正在系统学习中
注:本文转载自blog.csdn.net的总裁余(余登武)的文章"https://blog.csdn.net/kobeyu652453/article/details/107348229"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top