目录
数字图像属性
数字图像有多个通道(RGB、YUV、HSV等),每个通道是一个二维矩阵,矩阵的每个元素是0-255整数。
opencv-python环境搭建
安装python3.8,采用exe方式安装,pip会随之安装。修改环境变量path,添加C:\Python38和C:\Python38\Scripts。其中C:\Python38有python.exe,C:\Python38\Scripts里面有pip.exe。以管理员身份打开cmd,执行以下三个命令:
pip install --upgrade setuptools
pip install numpy Matplotlib
pip install opencv-python
安装numpy、Matplotlib、opencv-python三个包, opencv环境已经已经搭建好了。
如果安装失败,那么也可以到http://www.lfd.uci.edu/~gohlke/pythonlibs/下载numpy、matplotlib、opencv-python三个包,再本地安装,pip install <包名>。
或者,可以指定国内的开源镜像站,这样不会受到万里长城的干扰。我使用的是网易开源镜像站,推荐。以安装matplotlib为例。
pip install matplotlib -i http://uni.mirrors.163.com/pypi/simple/ --trusted-host uni.mirrors.163.com
基本操作
我们使用opencv-python环境,操作调用API可以参考这个地址的文档,里面有详细的说明。
Read in / Show out,读取、显示图像;
搭建好环境,就用读取、显示图像测试一下。使用cv2.imread读取经典的lena图像,可以直接读取彩色、灰度图像,cv2.imshow显示图像。
import cv2
# flags = 0 灰度图像
# flags = 1 彩色图像
img_color = cv2.imread('d:/dev/res/lena.jpg', flags=1)
img_gray = cv2.imread('d:/dev/res/lena.jpg', flags=0)
# 显示图片
cv2.imshow('lena_color', img_color)
cv2.imshow('lena_gray', img_gray)
# 等待输入ESC退出
key = cv2.waitKey()
if key == 27:
cv2.destroyWindow('lena_color')
cv2.destroyWindow('lena_gray')
pass
Change color,修改颜色;
加深颜色,我们让每个像素点R通道加100,那么整个图片会变更红。
import cv2
def rgb_add(image, channel, offset=0):
if abs(offset) <= 255 and channel.casefold() in ('r', 'g', 'b'):
if offset > 0:
b, g, r = cv2.split(image)
if channel.casefold() == 'r':
r[r > 255 - offset] = 255
r[r <= 255 - offset] = r[r <= 255 - offset] + offset
elif channel.casefold() == 'g':
g[g > 255 - offset] = 255
g[g <= 255 - offset] = g[g <= 255 - offset] + offset
elif channel.casefold() == 'b':
b[b > 255 - offset] = 255
b[b <= 255 - offset] = b[b <= 255 - offset] + offset
pass
image_merge = cv2.merge((b, g, r,))
return image_merge
elif offset < 0:
b, g, r = cv2.split(image)
if channel.casefold() == 'r':
r[r < abs(offset)] = 0
r[r >= abs(offset)] = r[r >= abs(offset)] + offset
elif channel.casefold() == 'g':
g[g < abs(offset)] = 0
g[g >= abs(offset)] = g[g >= abs(offset)] + offset
elif channel.casefold() == 'b':
b[b < abs(offset)] = 0
b[b >= abs(offset)] = b[b >= abs(offset)] + offset
pass
image_merge = cv2.merge((b, g, r,))
return image_merge
else:
return image
else:
return image
pass
img = cv2.imread('d:/dev/res/lena.jpg', flags=1)
img_r = rgb_add(img, channel='r', offset=-150)
cv2.imshow('lena', img)
cv2.imshow('lena_red', img_r)
key = cv2.waitKey()
if key == 27:
cv2.destroyAllWindows()
pass
Gamma Correction,伽马校正;
伽马校正的目的是使得图像变明亮清晰。校正的方式是,对每个像素每个通道的数值进行gamma校正,每个像素除以255,结果做gamma次幂,再乘以255,取整。gamma值再0至1之间使图像整体变得明亮清晰,一般取gamma=0.7可用。
import cv2
import numpy
def gamma_adjust(image, gamma=1.0):
table = []
for i in range(256):
table.append(((i / 255.0) ** gamma) * 255)
pass
table = numpy.array(table).astype('uint8')
image_gamma = cv2.LUT(image, table)
return image_gamma
pass
img = cv2.imread('d:/dev/res/dark.jpg', flags=1)
img_gamma = gamma_adjust(img, gamma=0.5)
cv2.imshow('img', img)
cv2.imshow('img_gamma', img_gamma)
key = cv2.waitKey()
if key == 27:
cv2.destroyAllWindows()
pass
Crop,切割;
从一个图像里面截取某一部分图像。比如从lena里截取面容。
import cv2
img = cv2.imread('d:/dev/res/lena.jpg', 1)
img_crop = img[80:200, 80:200]
print(img.shape)
cv2.imshow('lena', img)
cv2.imshow('lena_crop', img_crop)
key = cv2.waitKey()
if key == 27:
cv2.destroyAllWindows()
pass
Histogram,直方图
通过改变灰度图像各像素点的值,在保证不超过灰阶最大值的前提下,增强各像素点的对比,从而使图像增强,使图像变清晰。
关于直方图的原理,我就(说)不(不)说(明)了(白),个人认为这个cnblogs的博客对直方图原理写的比较好,直方图均衡化原理,推荐给大家。
import cv2
import matplotlib.pyplot as plt
img_gray = cv2.imread('d:/dev/res/lena.jpg', 0)
hist_gray = img_gray.flatten()
# bins 指的是统计区间分成个数
# range指的是统计区间
plt.hist(hist_gray, bins=256, range=[0, 256])
plt.show()
img_eq = cv2.equalizeHist(img_gray)
hist_eq = img_eq.flatten()
plt.hist(hist_eq, bins=256, range=[0, 256])
plt.show()
cv2.imshow('lena_gray', img_gray)
cv2.imshow('lena_hist', img_eq)
key = cv2.waitKey()
if key == 27:
cv2.destroyAllWindows()
pass