目錄
數字圖像屬性
數字圖像有多個通道(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