Python cv2 (二) 图像的灰度化 二值化 直方图 mask|均衡

1 灰度化 和二值化

按照颜色对图像进行分类

- 二值图像:0和1 ,0 表示黑色,1 表示白色。
- 灰度图像:[0,255] 表示灰度,如:0 表示纯黑,255 表示纯白。
- 彩色图像:BGR 三个色彩通道的组合表示。
1.1灰度化

灰度化图像:
①可以读取时候灰度化 cv2.imread(“dog.jpg”,0) # 0灰度
② 用命令转变 cv2.cvtColor(狗图,cv2.COLOR_BGR2GRAY)

狗图=cv2.imread("dog.jpg")
狗图_gray=cv2.imread("dog.jpg",0) # 0灰度
狗图_gray2=cv2.cvtColor(狗图,cv2.COLOR_BGR2GRAY)

在这里插入图片描述

1.2 二值化

二值图像,可以突出图像轮廓,把目标从背景中分割出来。

cv2.threshold(src, 阈值, 最大值, type)
		参数:
		阈值  0-255  需要调整合适值
		最大值 一般 255
		type:
			cv2.THRESH_BINARY:大于阈值时置 255,否则置 0
			cv2.THRESH_BINARY_INV:大于阈值时置 0,否则置 255
			cv2.THRESH_TRUNC:大于阈值时置为阈值 thresh,否则不变(保持原色)
阈值,狗图_二值化=cv2.threshold(狗图,120,255,cv2.THRESH_BINARY)
阈值,狗图_二值化_INV=cv2.threshold(狗图,120,255,cv2.THRESH_BINARY_INV)  
	# 小于阈值设为0, 否则255
阈值,狗图_二值化_TRUNC=cv2.threshold(狗图,120,255,cv2.THRESH_TRUNC)  
	# 大于阈值设为 阈值,否则不变色

2 灰度化转换

【目的】图像增强:动态范围扩大 图像对比度增强,图像更清晰,特征更明显,从而改善图像的显示效果。

【方法】按一定规则(灰度映射函数)修改图像每一个像素的灰度值,从而改变图像灰度的动态范围。
【分类】根据灰度映射函数的性质,灰度变换可以分:

种类 说明
反相 变换 反相每个像素值 ,增强 暗部区域的 白色和灰色细节
线性 变换 线性拉伸每个像素,凸显图像的细节,提高图像的对比度。
分段 线性变换
非线性 变换 - 最为常用。

2.1 反相

【思路】 读出每个像素值, 取补(255-n), 写进去
1,灰度化图片
2,新建黑色画布,等尺寸原图
3,用for循环,用原图每个像素的补数,填充画布的对应坐标
【目的】 增强 暗部区域的 白色和灰色细节

# 1, 读入图片
图片 = cv2.imread("lena.jpg")
# 2,灰度图片
图片_灰度=cv2.cvtColor(图片,cv2.COLOR_BGR2GRAY)

# 3 新建黑色等原图尺寸的图片
图片反相=np.zeros_like(图片)
w,h=图片.shape[:2]

# 4 填充用灰度图的每一个像素的补数,填充反相的对应坐标位置
for i in range(w):
    for j in range(h):
        图片反相[i][j]=255-图片_灰度[i][j]   # 用灰度图的每一个像素的补数,填充反相的对应坐标位置

在这里插入图片描述

2.2 线性 变换

线性拉伸每个像素,凸显图像的细节,提高图像的对比度
公式 Dt=αD+β , (D为原图灰度值,Dt为变换后的灰度值)

当 α = 1 , β = 0 ,原图不变
当 α = 1 , β > 0 ,灰度值上移,图像发白(彩色图像颜色发亮)
当 α = 1 , β < 0   , 灰度值下移,图像颜色发黑(彩色图像颜色发暗)

当 α > 1  ,图像的对比度增强
当 0<α<1 ,图像的对比度减小
当 α < 0 , β = 255,图像暗区域变亮,亮区域变暗,图像求补
当 α = − 1 ,β=255 时,图像的灰度值反转
  • 小步骤
    1, 读入图片并灰度化
    2, 创建新画布

     h, w = 图片.shape[:2]  # 图片的高度和宽度
    

    3, 画布1 = np.empty((w, h), np.uint8) # 创建空白数组

     画布1 = np.zeros_like(图片)  # 创建空白数组
     画布2 = np.zeros_like(图片)  # 创建空白数组
     画布3 = np.zeros_like(图片)  # 创建空白数组
     画布4 = np.zeros_like(图片)  # 创建空白数组
     画布5 = np.zeros_like(图片)  # 创建空白数组
     画布6 = np.zeros_like(图片)  # 创建空白数组
    

    4,线性化 像素 Dt[i,j] = a*D[i,j] + b

     for i in range(h) :
         for j in range(w) :
             画布1[i][j] = min(255, max((图片_灰度[i][j] + 50), 0))  # a=1,b>0: 颜色发白
             画布2[i][j] = min(255, max((图片_灰度[i][j] - 50), 0))  # a=1,b<0: 颜色发黑
             画布3[i][j] = min(255, max(1.5 * 图片_灰度[i][j], 0))  # a>1,b=0: 对比度增强
             画布4[i][j] = min(255, max(0.5 * 图片_灰度[i][j], 0))  # 0<a<1,b=0: 对比度减小
             画布5[i][j] = -0.5 * 图片_灰度[i][j] + 255  # a<0,b=255: 暗区域变亮,亮区域变暗
             画布6[i][j] = min(255, max(-1 * 图片_灰度[i][j] + 255, 0))  # a=-1,b=255: 灰度值反转
    

代码奉上

# coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt

# 1,读入并灰度
图片 = cv2.imread("lena.jpg")
图片_灰度 = cv2.cvtColor(图片, cv2.COLOR_BGR2GRAY)  # 颜色转换:BGR(OpenCV) -> Gray

# 2,创建新画布
h, w = 图片.shape[:2]  # 图片的高度和宽度
# 画布1 = np.empty((w, h), np.uint8)  # 创建空白数组
画布1 = np.zeros_like(图片)  # 创建空白数组
画布2 = np.zeros_like(图片)  # 创建空白数组
画布3 = np.zeros_like(图片)  # 创建空白数组
画布4 = np.zeros_like(图片)  # 创建空白数组
画布5 = np.zeros_like(图片)  # 创建空白数组
画布6 = np.zeros_like(图片)  # 创建空白数组

# 线性化 像素  Dt[i,j] = a*D[i,j] + b
for i in range(h) :
    for j in range(w) :
        画布1[i][j] = min(255, max((图片_灰度[i][j] + 50), 0))  # a=1,b>0: 颜色发白
        画布2[i][j] = min(255, max((图片_灰度[i][j] - 50), 0))  # a=1,b<0: 颜色发黑
        画布3[i][j] = min(255, max(1.5 * 图片_灰度[i][j], 0))  # a>1,b=0: 对比度增强
        画布4[i][j] = min(255, max(0.5 * 图片_灰度[i][j], 0))  # 0<a<1,b=0: 对比度减小
        画布5[i][j] = -0.5 * 图片_灰度[i][j] + 255  # a<0,b=255: 暗区域变亮,亮区域变暗
        画布6[i][j] = min(255, max(-1 * 图片_灰度[i][j] + 255, 0))  # a=-1,b=255: 灰度值反转


def bgr2rgb(cv2_img) :
    # 灰度图片直接返回
    if len(cv2_img.shape) == 2 :
        return cv2_img
    # 3通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 3 :  # 三位数,三通道
        b, g, r = cv2.split(cv2_img)
        return cv2.merge((r, g, b))
    # 4通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[
图像直方图可以使用Python中的OpenCV库中的calcHist函数进行计算。具体实现步骤如下: 1. 导入OpenCV库 ```python import cv2 ``` 2. 读取图像并转换为灰度图像 ```python img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ``` 3. 计算直方图 ```python hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) ``` 其中,[gray]表示输入的图像,[0]表示通道数,None表示没有使用mask,[256]表示直方图的bin数,[0, 256]表示像素值的范围。 4. 显示直方图 ```python import matplotlib.pyplot as plt plt.plot(hist) plt.show() ``` 5. 选择最佳阈值并二值化图像 根据直方图图像的灰度分布,可以选择一个合适的阈值将图像进行二值化。在这里,我们可以使用OpenCV库中的threshold函数实现。 ```python ret, thresh = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY) ``` 其中,gray表示输入的灰度图像,threshold_value表示阈值,255表示最大值,cv2.THRESH_BINARY表示二值化类型。 完整代码如下: ```python import cv2 import matplotlib.pyplot as plt # 读取图像并转为灰度图像 img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 计算直方图 hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) # 显示直方图 plt.plot(hist) plt.show() # 选择最佳阈值并二值化图像 threshold_value = 127 ret, thresh = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY) # 显示二值化后的图像 cv2.imshow('Binary Image', thresh) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值