OpenCV--Python 图像的基本操作

数字图像处理的本质就是操作矩阵,在Python中图像对应的Numpy的ndarray。所以做图像处理会使用numpy会很方便的。

1.图像的读、写、显示

cv2.imread("图像路径名",读取方式)
读取方式有:
    IMREAD_ANYCOLOR = 4
    IMREAD_ANYDEPTH = 2
    IMREAD_COLOR = 1
    IMREAD_GRAYSCALE = 0
    IMREAD_LOAD_GDAL = 8
    IMREAD_UNCHANGED = -1
通常读取方式可以不写,默认是以BGR彩色图片读取的;或者读取方式写0,表示以灰度图的方式读取。

其他简单的函数代码中解释:

import cv2 as cv
img = cv.imread("./images/xiao.jpg")
cv.namedWindow("xiao")        # 创建名字为xiao的窗口(不创建也可以)
cv.imwrite("jiang.jpg", img)  # 将img存到本地,名字为jiang.jpg
cv.imshow("xiao", img)        # 在xiao窗口中显示图片img
cv.waitKey()                  # 等待按键ESC退出窗口
cv.destoryAllWindows()        # 释放由OpenCV创建的所有窗口

其中imwrite()也可以保存为图像的其他格式(jpg, png),也可以选择保存的图片质量

cv.imwrite("jiang1.jpg", img, [int(cv.IMWRITE_JPEG_QUALITY), 5])
cv.imwrite("jiang2.jpg", img, [int(cv.IMWRITE_JPEG_QUALITY), 100])
# 对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。
# 注意,cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int。
cv.imwrite("jiang3.png", img, [int(cv.IMWRITE_PNG_COMPRESSION), 0])
cv.imwrite("jiang4.png", img, [int(cv.IMWRITE_PNG_COMPRESSION), 9])
# 对于PNG,第三个参数表示的是压缩级别。cv2.IMWRITE_PNG_COMPRESSION,
# 从0到9,压缩级别越高,图像尺寸越小。默认级别为3.

2.图像的加、混合、位运算

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
    此函数可以用表达式计算:
        dst = src1 * alpha + src2 * beta + gamma
    dtype为输出图像的深度,当两个图像是相同的话为-1(一般不作设置)
    此函数中的两幅图像必须是尺寸相同、类型相同的。alpha+beta=1,分别取不同的值有不同的效果。

图像的位操作:图像与运算cv2.bitwise_and,图像或运算cv2.bitwise_or,图像非运算cv2.bitwise_not与图像异或运算cv2.bitwise_xor。
    1)图像与运算-cv2.bitwise_and(src1, src2, dst=None, mask = None)
    2)图像或运算-cv2.bitwise_or(src1, src2, dst=None, mask = None)
    3)图像非运算-cv2.bitwise_not(src1, src2, dst=None, mask = None)
         图像非运算的效果:一个二值图,将黑色转为白色,白色转为黑色。
    4) 图像异或运算-cv2.bitwise_xor(src1, src2, dst=None, mask = None)
    这四个运算,最少要有两个参数,即src1,src2;dst:参数返回结果可选;mask:参数也是可选的,指定mask区域进行操作。

import numpy as np
import cv2 as cv
img1 = cv.imread("./images/xiao.jpg")
img2 = cv.imread("./images/er.jpg")
mask = np.zeros((200, 200), np.uint8)  # 创建一个掩膜(全黑)
mask[50:150, 50:150] = 255             # 将掩膜中间部分变为白的
mask_inv = cv.bitwise_not(mask)        # 反转颜色

res = cv.add(img1, img1)               # 图像加法 将img1与img1相加
dst = cv.addWeighted(img1, 0.5, img2, 0.5, 0)  # 根据权重将两张图片相加
# 与掩码mask进行位运算,只显示中间部分
img_mask = cv.bitwise_and(img1, img1, mask=mask)
# 与掩码mask_inv进行位运算,只显示除中间以外部分
img_mask_inv = cv.bitwise_and(img2, img2, mask=mask_inv)

cv.imshow("img1", img1)
cv.imshow("img2", img2)
cv.imshow("res", res)
cv.imshow("dst", dst)
cv.imshow("mask1", img_mask)
cv.imshow("mask2", img_mask_inv)
cv.waitKey()
cv.destoryAllWindows()

下图为运行结果:

3.图像通道的拆分与合并

读入BGR图像之后,可以对图像的各个通道进行拆分(cv2.split)分别得到三个通道,也可以对三个通道进行合并得到BGR图像。下面使用OpenCV的函数以及Numpy操作对图像实现拆分与合并,图像的0,1,2通道分别对应B,G,R三个通道

import cv2 as cv
import numpy as np
img = cv.imread("./images/er.jpg")

# 使用numpy进行分割
# b = np.zeros((img.shape[0], img.shape[1]), dtype=img.dtype)
# g = np.zeros((img.shape[0], img.shape[1]), dtype=img.dtype)
# r = np.zeros((img.shape[0], img.shape[1]), dtype=img.dtype)

# b[:, :] = img[:, :, 0]  # B蓝色通道
# g[:, :] = img[:, :, 1]  # G绿色通道
# r[:, :] = img[:, :, 2]  # R红色通道
# 使用OpenCV进行分割
b, g, r = cv.split(img)

# 使用OpenCV进行合并
merged = cv.merge([b, g, r])
print("Merge by OpenCV")
print(merged.strides)
print(merged)

# 使用Numpy进行合并
mergedByNp = np.dstack([b, g, r])
print("Merge by NumPy ")
print(mergedByNp.strides)
print(mergedByNp)

cv.imshow("Merged", merged)
cv.imshow("MergedByNp", mergedByNp)
cv.imshow("Blue", b)
cv.imshow("Red", r)
cv.imshow("Green", g)
cv.waitKey(0)
cv.destroyAllWindows()

可能红绿蓝通道和自己想的不一样,为了转换为我所想的,所以这里需要把b,g,r所对应的单通道转换为三通道的,其余两个通道使用0填充即可,添加以下代码,实现了自己原本想象的红绿蓝通道的图像:

zeros = np.zeros(img.shape[:2], np.uint8)
b = cv.merge([b, zeros, zeros])
g = cv.merge([zeros, g, zeros])
r = cv.merge([zeros, zeros, r])

图像的基本操作还有很多,基于Numpy可以改变某个像素的值或者多个像素的值,这里就不做介绍了(懂点Numpy的应该都会做吧),主要是要对数字图像和Numpy的ndarray有些了解,今天先到这里吧。

图像的处理还是很好玩的,继续坚持,每天学一点,加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CharlesWu123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值