基于opencv的图像操作——图片比较、缩放图片、图片边缘填充、对比度增强、图像二值化等

基于opencv的图像操作

1. 比较两张图片

import cv2
import numpy as np
#import os
 

def is_same(img1, img22):
    image1 = cv2.imread(img1)
    image2 = cv2.imread(img22)
    difference_1 = cv2.subtract(image1, image2)
    difference_2 = cv2.subtract(image2, image1)
    # print(difference)
    result = not np.any(difference_1) #if difference is all zeros it will return False
    if result:
        result = not np.any(difference_2) #if difference is all zeros it will return False
    
    if result is True:
        print("两张图片一样")
    else:
        cv2.imwrite("result.jpg", difference)
        print ("两张图片不一样")

if __name__=='__main__':
    file1= "1.png"
    file2="2.png"
    
    is_same(file1, file2)

2. resize()缩放图像

'''
	cv2.resize(img, (w,h), interpolation)
        img -> 输入图像
        w,h -> 缩放后的图像尺寸
        interpolation -> 缩放图像的方法,
                   1. cv2.INTER_NEAREST  # 最邻近差值法
                   2. cv2.INTER_LINEAR   # 双线性差值法
                   3. cv2.INTER_AREA     # 基于局部像素的重采样法
                   4. cv2.INTER_CUBIC    # 三次差值法
                   5. cv2.INTER_LANCZOS4 # 基于8*8像素邻域的Lanczos差值法                      			(cv2.INTER_AREA方法能够最大程度保证图像的缩放质量)
'''
import cv2
import numpy as np

def rescale(img, STANDARD_HWIGHT=32):
    '''
        将图像转化为高度为STANDARD_HWIGHT的图像
        @param:  img -> np.ndarray  img.shape = [ H x W x C ]
        @return:
    '''
    scale = img.shape[0] * 1.0 / 32
    w = img.shape[1] / scale
    w = int(w)
    # img = cv2.resize(img, (w, 32), interpolation=cv2.INTER_NEAREST)
    # img = cv2.resize(img, (w, 32), interpolation=cv2.INTER_AREA)
    # img = cv2.resize(img,(w, 32), interpolation=cv2.INTER_CUBIC)
    img = cv2.resize(img,(w, 32), interpolation=cv2.INTER_LANCZOS4)  # 基于8*8像素邻域的Lanczos差值法
    img = np.array(img, dtype=np.uint8)


if __name__ == '__main__':
    img = cv2.imread('test.png')
    new_img = rescale(img)
    cv2.imwrite('new.png', new_img)

3. 图像边缘填充 copyMakeBorder

'''
	cv2.copyMakeBorder(src, dist, top, bottom, left, right, borderType, value)
		src -> 输入的图像
		dist -> 
		top, bottom, left, right -> 相应方向上的边框宽度
		borderType -> 想要添加的边框类型
				cv2.BORDER_CONSTANT:添加的边界框像素值为常数(需要额外再给定一个参数)
				cv2.BORDER_REFLECT:添加的边框像素将是边界元素的镜面反射,类似gfedcb|abcdefgh|gfedcba
				cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT:和上面类似,但是有一些细微的不同
				cv2.BORDER_REPLICATE:使用最边界的像素值代替,类似于aaaaaa|abcdefgh|hhhhhhh
				cv2.BORDER_WRAP:
		value -> borderType为cv2.BORDER_CONSTANT时需要填充的常数值
'''

import cv2

img1 = cv2.imread('new_imgs/amount_0_1.png')
print(img1.shape)

# WHITE = [255,255,255]
# img6 = cv2.copyMakeBorder(img1,0,0,10,20,cv2.BORDER_CONSTANT,value=WHITE)
img6 = cv2.copyMakeBorder(img1,200,200,200,200,cv2.BORDER_REPLICATE)

cv2.imwrite('new.png', img6)
print(img6.shape)

4. 对比度增强

reference: https://blog.csdn.net/qq_40755643/article/details/84032773

4.1 直方图归一化
'''
cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]]) → dst

src-输入数组
dst-输出数组,支持原地运算
alpha-range normalization模式的最小值
beta-range normalization模式的最大值,不用于norm normalization(范数归一化)模式。
normType-归一化的类型,可以有以下的取值:
    NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。
    NORM_INF: 此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)
    NORM_L1 :  归一化数组的L1-范数(绝对值的和)
    NORM_L2: 归一化数组的(欧几里德)L2-范数
dtype-dtype为负数时,输出数组的type与输入数组的type相同;否则,输出数组与输入数组只是通道数相同,而tpye=CV_MAT_DEPTH(dtype).
mask-操作掩膜,用于指示函数是否仅仅对指定的元素进行操作。

适用于:灰度级主要在0~150之间,造成图像对比度较低,可用直方图归一化将图像灰度级拉伸到0~255,使其更清晰。
'''

import cv2
import numpy as np
 
#灰度图像转化为ndarray类型
I = cv2.imread(r'test_img/1.png')
 
dst = np.zeros_like(I)
cv2.normalize(I, dst, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U) 
cv2.imwrite('new.png', dst)
4.2 直方图均衡化HE
'''
cv2.equalizeHist(image)

直方图均衡化是将原始的直方图拉伸,使之均匀分布在全部灰度范围内,从而增强图像的对比度。
直方图均衡化的中心思想是把原始图像的的灰度直方图从比较集中的某个区域变成在全部灰度范围内的均匀分布。旨在使得图像整体效果均匀,黑与白之间的各个像素级之间的点更均匀一点。
'''
import cv2
import numpy as np

def HE_1()
	'''
		灰度图像直方图均衡
	'''
    #灰度图像转化为ndarray类型
    I = cv2.imread(r'test_img/1.png',  cv2.IMREAD_GRAYSCALE)

    O = cv2.equalizeHist(I)

    cv2.imwrite('new.png', O)

    
def HE_2():
    '''
    	彩色图像直方图均衡
    '''
    #灰度图像转化为ndarray类型
    I = cv2.imread(r'test_img/1.png', cv2.IMREAD_ANYCOLOR)

    b, g, r = cv2.split(I)

    b1 = cv2.equalizeHist(b)
    g1 = cv2.equalizeHist(g)
    r1 = cv2.equalizeHist(r)

    O = cv2.merge([b1,g1,r1])

    cv2.imwrite('new.png', O)
4.3 5.伽马变换
'''
伽马变换(非线性变换)实际上就是对矩阵的每个值进行幂运算
适用于:灰度值主要集中在灰度直方图两侧,即灰度值较低和较高的范围内,可用伽马变换修正
'''
import cv2
import numpy as np
 
#灰度图像转化为ndarray类型
I = cv2.imread(r'test_img/region_1.png', cv2.IMREAD_ANYCOLOR)

#图像归一化
fI = I/255.0
#伽马变化
gamma = 0.4
O = np.power(fI, gamma)

cv2.imwrite('new.png', O*255)
4.3.4 线性变换
'''
拉伸灰度级,提高对比度
压缩灰度级,降低对比度
'''
import cv2
import numpy as np
 
#灰度图像转化为ndarray类型
I = cv2.imread(r'test_img/region_1.png', cv2.IMREAD_ANYCOLOR)

#线性变换
a = 2
O = float(a) * I
O[O>255] = 255 #大于255要截断为255
    
#数据类型的转换
O = np.round(O)
O = O.astype(np.uint8)

cv2.imwrite('new.png', O*255)

5. 图像二值化

import cv2

def to_gray_1(img):
    yuzhi = 100       #二值化的阈值
    
    # 二值化
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)           # 将彩色图像转化为灰度图
    ret, th3 = cv2.threshold(gray_img, yuzhi, 255, cv2.THRESH_BINARY_INV)
    img = cv2.cvtColor(th3, cv2.COLOR_GRAY2BGR)                # 将灰度图转化为彩色图像

    return img

6. cv2.imread()读取图像的注意事项

使用cv2.imread()读取彩色图像后得到的格式是BGR格式,像素值范围在0~255之间,通道格式为(H,W,C)
img = cv2.imread(path)

若想要显示RGB类型的图像要进行一步格式转换。
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

直接用Image等库读取图像的话貌似不需要进行格式转换。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值