【OpenCV C++&Python】(四)图像阈值处理

简介:

图像阈值处理

Python

简单阈值处理

OpenCV的cv.threshold用于简单阈值处理,它的第一个参数是灰度源图像src;第二个参数是阈值thresh;第三个参数是赋值给超过阈值的像素的最大值maxval;第四个参数则是阈值处理的类型:

cv.threshold返回两个输出。第一个是使用的阈值,第二个输出是阈值图像dst。下面比较不同类型的阈值处理方法:

import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np

img = cv.imread('threshold.jpg', 0)
ret, thresh1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret, thresh2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
ret, thresh3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
ret, thresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
ret, thresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

自适应阈值处理

简单阈值处理在图像全局都使用同一个阈值,如果图像在不同区域有不同的照明条件,这可能就不适用了。在这种情况下,自适应阈值处理更适合。自适应阈值处理根据像素周围的一个小区域来确定阈值。可以使用OpenCV的cv.adaptiveThreshold实现这个功能。

cv.adaptiveThreshold的第一个参数是灰度源图像src;第二个参数是赋值给超过阈值的像素的最大值maxval

第三个参数adaptiveMethod决定如何计算阈值:

  • cv.ADAPTIVE_THRESH_MEAN_C:阈值是邻域内像素的平均值减去常数C
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C:阈值是邻域内像素的高斯加权和减去常数C

第四个参数则是阈值处理的类型;第五个参数 blockSize决定邻域区域的大小;第六个参数是常数C

下面对比一下简单阈值处理和自适应阈值处理:

import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('adaptiveThreshold.jpg', 0)
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
th2 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 2)
th3 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 2)

titles = ['Original Image', 'BINARY(v=127)',
          'ADAPTIVE_THRESH_MEAN_C', 'ADAPTIVE_THRESH_GAUSSIAN_C']
images = [img, th1, th2, th3]
for i in range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

大津(Otsu)法

原理

使用cv.threshold()函数,阈值处理的类型可以任意选择,THRESH_OTSU作为一个额外的flag即可使用大津法。下面以一个直方图包含两个峰的图像(双峰图像)为例:

import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('coins.png', 0)
# 普通二值化
ret1, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
# Otsu法二值化
ret2, th2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)  # 随便给个0为阈值

images = [img, [], th1,
          img, [], th2]
titles = ['Original Image', 'Histogram', 'BINARY (v=127)',
          'Original Image', 'Histogram', 'OTSU(v=0)']
for i in range(2):
    plt.subplot(2, 3, i * 3 + 1), plt.imshow(images[i * 3], 'gray')
    plt.title(titles[i * 3]), plt.xticks([]), plt.yticks([])
    plt.subplot(2, 3, i * 3 + 2), plt.hist(images[i * 3].ravel(), 256)
    plt.title(titles[i * 3 + 1]), plt.xticks([]), plt.yticks([])
    plt.subplot(2, 3, i * 3 + 3), plt.imshow(images[i * 3 + 2], 'gray')
    plt.title(titles[i * 3 + 2]), plt.xticks([]), plt.yticks([])
plt.show()

大津法无需人工指定阈值即可达到较为理想的效果。

C++

简单阈值处理

#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
    Mat img = imread("threshold.jpg",0);
    Mat thresh1, thresh2, thresh3, thresh4, thresh5;
    
    threshold(img, thresh1, 127, 255, THRESH_BINARY);
    threshold(img, thresh2, 127, 255, THRESH_BINARY_INV);
    threshold(img, thresh3, 127, 255, THRESH_TRUNC);
    threshold(img, thresh4, 127, 255, THRESH_TOZERO);
    threshold(img, thresh5, 127, 255, THRESH_TOZERO_INV);

    imshow("Original Image", img);
    imshow("BINARY", thresh1);
    imshow("BINARY_INV", thresh2);
    imshow("TRUNC", thresh3);
    imshow("TOZERO", thresh4);
    imshow("TOZERO_INV", thresh5);
    waitKey(0);
    return 0;
}

自适应阈值处理

#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
    Mat img = imread("adaptiveThreshold.jpg",0);
    Mat thresh1, thresh2, thresh3;
    threshold(img, thresh1, 127, 255, THRESH_BINARY);
    adaptiveThreshold(img, thresh2,255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, 2);
    adaptiveThreshold(img, thresh3,255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2);

    imshow("Original Image", img);
    imshow("BINARY", thresh1);
    imshow("ADAPTIVE_THRESH_MEAN_C", thresh2);
    imshow("ADAPTIVE_THRESH_GAUSSIAN_C", thresh3);
    waitKey(0);
    return 0;
}

大津(Otsu)法

#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
    Mat img = imread("coins.png",0);
    Mat thresh1, thresh2;
    threshold(img, thresh1, 127, 255, THRESH_BINARY);
    threshold(img, thresh2, 0, 255, THRESH_BINARY + THRESH_OTSU);

    imshow("Original Image", img);
    imshow("BINARY", thresh1);
    imshow("OTSU", thresh2);
    waitKey(0);
    return 0;
}

代码:
https://gitee.com/BinaryAI/open-cv-c--and-python

参考:

[1]https://docs.opencv.org/4.6.0/

[2]https://zhuanlan.zhihu.com/p/384457101

[3]数字图像处理(MATLAB版)(第2版),张德丰, 人民邮电出版社

相关文章
|
5月前
|
jenkins Shell 测试技术
|
5月前
|
安全 jenkins Java
Java、Python、C++支持jenkins和SonarQube(一)
Jenkins 是一个开源的 持续集成(CI)和持续交付(CD) 工具,用于自动化构建、测试和部署软件项目。它基于 Java 开发,支持跨平台运行,并拥有丰富的插件生态系统,可以灵活地扩展功能
366 5
|
5月前
|
jenkins Java Shell
Java、Python、C++支持jenkins和SonarQube(全集)
Jenkins 是一个开源的持续集成(CI)和持续交付(CD)工具,用于自动化构建、测试和部署软件项目。它基于 Java 开发,支持跨平台运行,并拥有丰富的插件生态系统,可以灵活地扩展功能
509 1
|
5月前
|
jenkins Java 持续交付
Java、Python、C++支持Jenkins和SonarQube(三)
Python与Jenkins和SonarQube
194 1
|
5月前
|
jenkins Java 测试技术
|
11月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【害虫识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
害虫识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了12种常见的害虫种类数据集【"蚂蚁(ants)", "蜜蜂(bees)", "甲虫(beetle)", "毛虫(catterpillar)", "蚯蚓(earthworms)", "蜚蠊(earwig)", "蚱蜢(grasshopper)", "飞蛾(moth)", "鼻涕虫(slug)", "蜗牛(snail)", "黄蜂(wasp)", "象鼻虫(weevil)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Djan
643 1
基于Python深度学习的【害虫识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
蘑菇识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了9种常见的蘑菇种类数据集【"香菇(Agaricus)", "毒鹅膏菌(Amanita)", "牛肝菌(Boletus)", "网状菌(Cortinarius)", "毒镰孢(Entoloma)", "湿孢菌(Hygrocybe)", "乳菇(Lactarius)", "红菇(Russula)", "松茸(Suillus)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,
1181 11
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
|
12月前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
462 12
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
4062 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
307 4

推荐镜像

更多