博客
关于我
OpenCV threshold函数详解
阅读量:291 次
发布时间:2019-03-01

本文共 7931 字,大约阅读时间需要 26 分钟。

OpenCV阈值函数详解

阈值函数(Threshold Function)是图像处理中的一个基本操作,常用于去噪、边缘检测等场景。通过对图像像素值进行比对,设置一个阈值,根据结果将像素值置零或设定为最大值,从而实现图像的二值化处理。

阈值函数的作用

阈值函数的主要作用是对图像进行二值化处理。通过设置一个阈值,图像中的像素值如果高于或低于该阈值,会被替换为0或最大值(通常是255)。这种方法可以有效地去噪,提取图像中的边缘或特定区域。

Python版阈值函数原型

retval, dst = cv.threshold(src, thresh, maxval, type[, dst])

参数说明

  • src:原图像。
  • dst:结果图像。
  • thresh:当前阈值。
  • maxval:最大阈值,通常为255。
  • type:阈值类型,常见有以下几种:
阈值类型 对应值 特殊说明
THRESH_BINARY 0 二值化,>thresh置255,<=thresh置0
THRESH_BINARY_INV 1 二值化,>thresh置0,<=thresh置255
THRESH_TRUNC 2 截断,大于thresh的值置maxval
THRESH_TOZERO 3 到零,大于thresh的值保留原值,<=thresh置0
THRESH_TOZERO_INV 4 到零,>thresh置0,<=thresh保留原值
THRESH_MASK 7 二值掩膜,不支持32位图像
THRESH_OTSU 8 门限值优化,仅支持单通道图像
THRESH_TRIANGLE 16 三角形门限值优化,不支持32位图像

返回值

  • retval:与参数thresh一致。
  • dst:结果图像。

阈值类型详解

1. THRESH_BINARY

将图像中大于thresh的像素值设为255,小于等于thresh的设为0。

ret, dst = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)

2. THRESH_BINARY_INV

与THRESH_BINARY相反,大于thresh的值置0,小于等于thresh的值置255。

ret, dst = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV)

3. THRESH_TRUNC

将大于thresh的像素值截断至maxval,其余值保持不变。

ret, dst = cv2.threshold(img, 128, 255, cv2.THRESH_TRUNC)

4. THRESH_TOZERO

将大于thresh的像素值保留原值,小于等于thresh的值置0。

ret, dst = cv2.threshold(img, 128, 255, cv2.THRESH_TOZERO)

5. THRESH_TOZERO_INV

与THRESH_TOZERO相反,>thresh置0,<=thresh保留原值。

ret, dst = cv2.threshold(img, 131, 255, cv2.THRESH_TOZERO_INV)

6. THRESH_OTSU

用于自动门限值选择,结合其他阈值类型使用,仅适用于单通道图像。

7. THRESH_TRIANGLE

与OTSU类似,用于三角形门限值优化,仅支持单通道图像。

示例代码

以下是一个使用OpenCV进行阈值处理的Python代码示例:

import numpy as npimport cv2# 创建一个6x6的BGR三通道图像img = np.zeros((6, 6, 3), dtype=np.uint8)# 生成随机像素值img[:, :, 0] = np.random.randint(0, 100, size=36).reshape(6, 6)  # 蓝色通道img[:, :, 1] = np.random.randint(100, 200, size=36).reshape(6, 6)  # 绿色色通道img[:, :, 2] = np.random.randint(200, 256, size=36).reshape(6, 6)  # 红色通道# 使用THRESH_BINARY进行阈值处理ret, dst = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)print("阈值处理后的图像:")print(dst)

输出结果

[[[  0 255 255]  [  0   0 255]  [  0 255 255]  [  0   0 255]  [  0 255 255]  [  0   0 255]][[  0   0 255]  [  0 255 255]  [  0 255 255]  [  0 255 255]  [  0 255 255]  [  0   0 255]][[  0 255 255]  [  0 255 255]  [  0   0 255]  [  0 255 255]  [  0 255 255]  [  0   0 255]][[  0 255 255]  [  0 255 255]  [  0 255 255]  [  0 255 255]  [  0 255 255]  [  0 255 255]][[  0   0 255]  [  0   0 255]  [  0 255 255]  [  0   0 255]  [  0 255 255]  [  0   0 255]][[  0 255 255]  [  0 255 255]  [  0   0 255]  [  0   0 255]  [  0 255 255]  [  0 255 255]]

注意事项

  • THRESH_OTSU和THRESH_triangle仅适用于单通道图像。
  • 使用OTSU和triangle阈值时,需确保输入图像为灰度图像。
  • 门限值优化算法适用于自动选择最佳阈值,但需要结合其他阈值类型使用。

实用工具

以下是一个使用PyQt5编写的图像阈值处理 GUI 工具示例:

import cv2import numpy as npfrom PyQt5.QtWidgets import (QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QLabel,                            QFileDialog, QHBoxLayout, QLCDNumber, QProgressBar)from PyQt5.QtCore import Qt, QTimerclass ThresholdDemo(QWidget):    def __init__(self):        super().__init__()        self.setup_ui()        self.setup_slots()    def setup_ui(self):        self.title = "阈值处理工具"        self.setGeometry(100, 100, 800, 600)        self.img_path = ""        self.threshold = 1        self.max_val = 255        self.threshold_type = cv2.THRESH_BINARY        self.extend_type = 0        self.check_gray = False        # UI组件        self.main_layout = QVBoxLayout()        self.top_layout = QHBoxLayout()        self.param_layout = QVBoxLayout()        self.button_layout = QVBoxLayout()        # 参数设置        self.param_layout.addWidget(QLabel("阈值:"))        self.param_layout.addWidget(QLCDNumber(self.threshold))        self.param_layout.addWidget(QLabel("最大值:"))        self.param_layout.addWidget(QLCDNumber(self.max_val))        self.param_layout.addWidget(QLabel("阈值类型:"))        self.param_layout.addWidget(QComboBox(['THRESH_BINARY', 'THRESH_BINARY_INV',                                          'THRESH_TRUNC', 'THRESH_TOZERO',                                          'THRESH_TOZERO_INV', 'THRESH_OTSU',                                          'THRESH_TRIANGLE']))        # 按钮        self.button_layout.addWidget(QPushButton("浏览图片"))        self.button_layout.addWidget(QPushButton("更新阈值"))        self.button_layout.addWidget(QPushButton("切换灰度"))        self.button_layout.addWidget(QPushButton("查看帮助"))        # 显示区域        self.image_display = QLabel()        self.image_display.setFixedSize(640, 480)        self.main_layout.addWidget(self.image_display)        # 布局设置        self.top_layout.addLayout(self.param_layout)        self.top_layout.addLayout(self.button_layout)        self.setLayout(self.main_layout)    def setup_slots(self):        # 浏览图片按钮        self.btnBrowse.clicked.connect(self.slot_btn_browse)        # 阈值参数变化        self.threshold LCD绑定self.slot_threshold_changed        # 最大值参数变化        self.max_val LCD绑定self.slot_max_val_changed        # 阈值类型变化        self.threshold_type_combobox绑定self.slot_threshold_type_changed        # 灰度切换        self.btnCheckGray.toggled.connect(self.slot_check_gray)    def slot_btn_browse(self):        try:            file, _ = QFileDialog.getOpenFileName(self, 'Open Image', 'D:\\tmp\\pics', '*.*')            if file:                self.imagePath.setText(file)                img_init = cv2.imdecode(np.fromfile(file, dtype=np.uint8), -1)                self.img_threshold = img_init.copy()                cv2.cvtColor(img_init, cv2.COLOR_BGR2RGB, img_init)                h, w, c = img_init.shape                qImg = QImage(img_init, w, h, w * c, QImage.Format_RGB888)                self.initPicFrame.setPixmap(QPixmap.fromImage(qImg))                self.update_threshold_image()        except Exception as e:            print(e)    def update_threshold_image(self):        try:            img = self.img_threshold.copy()            if self.check_gray:                img_gray = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8)                cv2.cvtColor(img, cv2.COLOR_BGR2GRAY, img_gray)                ret, img_threshold = cv2.threshold(img_gray, self.threshold, self.max_val,                                                    self.threshold_type | self.extend_type)            else:                ret, img_threshold = cv2.threshold(img, self.threshold, self.max_val,                                                    self.threshold_type)            print(f"thresh: {self.threshold}, maxval: {self.max_val}, flags: {self.threshold_type} | {self.extend_type}")            h, w = img_threshold.shape            qImg = QImage(img_threshold, w, h, w, QImage.Format_Indexed8)            self.thresholdPicFrame.setPixmap(QPixmap.fromImage(qImg))        except Exception as e:            print(e)    def slot_threshold_changed(self, val):        self.threshold = val        self.threshold LCD显示更新        self.update_threshold_image()    def slot_max_val_changed(self, val):        self.max_val = val        self.max_val LCD显示更新        self.update_threshold_image()    def slot_threshold_type_changed(self, type):        type_dict = {            'THRESH_BINARY': cv2.THRESH_BINARY,            'THRESH_BINARY_INV': cv2.THRESH_BINARY_INV,            'THRESH_TRUNC': cv2.THRESH_TRUNC,            'THRESH_TOZERO': cv2.THRESH_TOZERO,            'THRESH_TOZERO_INV': cv2.THRESH_TOZERO_INV,            'THRESH_OTSU': cv2.THRESH_OTSU,            'THRESH_TRIANGLE': cv2.THRESH_TRIANGLE        }        self.threshold_type = type_dict[type]        self.update_threshold_image()    def slot_check_gray(self, bGray):        self.check_gray = bGray        self.update_threshold_image()def thresholdDemo():    img = np.zeros((6, 6, 3), dtype=np.uint8)    img[:, :, 0] = np.random.randint(0, 100, size=36).reshape(6, 6)    img[:, :, 1] = np.random.randint(100, 200, size=36).reshape(6, 6)    img[:, :, 2] = np.random.randint(200, 256, size=36).reshape(6, 6)    cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)    if __name__ == '__main__':        qApp = QApplication(sys.argv)        demo = ThresholdDemo()        demo.show()        qApp.exec_()

完整代码下载

请访问开源代码下载页面获取最新版本。

转载地址:http://gdco.baihongyu.com/

你可能感兴趣的文章
Objective-C实现感知哈希算法(附完整源码)
查看>>
Objective-C实现截留雨水问题的动态编程方法算法(附完整源码)
查看>>
Objective-C实现截留雨水问题的蛮力方法的算法(附完整源码)
查看>>
Objective-C实现打印10000以内的完数(附完整源码)
查看>>
Objective-C实现打印1000以内的水仙花数(附完整源码)
查看>>
Objective-C实现打印九九乘法表(附完整源码)
查看>>
Objective-C实现打印从 0 到 n 的卡特兰数算法(附完整源码)
查看>>
Objective-C实现打印函数调用堆栈( 附完整源码)
查看>>
Objective-C实现打印月份的日历算法(附完整源码)
查看>>
Objective-C实现打印杨辉三角(附完整源码)
查看>>
Objective-C实现打印某年的历法日期(附完整源码)
查看>>
Objective-C实现打印魔方矩阵(附完整源码)
查看>>
Objective-C实现打格点算法(附完整源码)
查看>>
Objective-C实现批量修改文件类型算法(附完整源码)
查看>>
Objective-C实现找出一个数的质因数primeFactors算法(附完整源码)
查看>>
Objective-C实现找出三角形从上到下的最大路径算法(附完整源码)
查看>>
Objective-C实现找出买卖股票的最大利润算法(附完整源码)
查看>>
Objective-C实现找出买卖股票的最大利润算法(附完整源码)
查看>>
Objective-C实现找出二维数组中的鞍点(附完整源码)
查看>>
Objective-C实现找出由两个 3 位数字的乘积构成的最大回文数的算法 (附完整源码)
查看>>