视频链接 : https://edu.csdn.net/course/play/10552
https://download.csdn.net/download/Sun_Raiser/12606889
i = cv2.imread("E:\\lesson\\image\\test.png")
cv2.imwrite("E:\\lesson\\image\\lesson1.png", i)
i = cv2.imread("image\\lena256.bmp", cv2.IMREAD_UNCHANGED)
i[100, 100] = 255
numpy :
i.itemset((100, 100), 255)
i[100,100]=[255,255,255]
numpy:
i.itemset((100, 100, 2), 255)
元组内第三个参数可以是0,1,2,分别对应b,g,r
a = cv2.imread("image\lena256.bmp", cv2.IMREAD_UNCHANGED)
print(a.shape)
print(a.size)
print(a.dtype)
a = cv2.imread("image\lenacolor.png", cv2.IMREAD_UNCHANGED)
#face = np.ones((101, 101, 3)) 可写可不写
face = a[220:400, 250:350]
a = cv2.imread("image\lenacolor.png")
b, g, r = cv2.split(a)
bgr = cv2.merge([b, g, r])
g、b、r顺序的调换会影响到图片的效果
a = cv2.imread("image\lena512.bmp")
b = a
result1 = a + b
result2 = cv2.add(a, b)
一种是opencv的加法,另一种是重载运算符的加法
重载运算符的加法,当两数之和大于256时,进行求模运算
opencv的add函数,当两数之和大于256时,取256为最大值
result = cv2.addWeighted(a, 1, b, 1, 0)
第二,第四个参数为权重,第五个参数调节亮度
a = cv2.imread("image\\lenacolor.png")
b = cv2.cvtColor(a, cv2.COLOR_BGR2GRAY)
参数可以是(包括但不限于):
cv2.COLOR_BGR2RGB
cv2.COLOR_GRAY2BGR
指定大小:
b = cv2.resize(a, (200, 100))
# 注意:第2个参数控制的是“列长度、行长度”,注意顺序。
或者
size = (200, 100)
b = cv2.resize(a, size)
# 注意:第2个参数控制的是“列长度、行长度”,注意顺序。
按比例缩放:
b = cv2.resize(a, (round(cols * 0.5), round(rows * 1.2)))
resize函数的参数必须是整数,所以要使用round函数取整
或者
rows, cols = a.shape[:2]
size = (round(cols * 0.5), round(rows * 1.2))
b = cv2.resize(a, size)
或者
b = cv2.resize(a, None, fx=1.2, fy=0.5)
b = cv2.flip(a, -1)
参数小于0,关于xy旋转;参数大于0,关于左右;0时,上下翻转
平移:
height, width = a.shape[:2]
x = 100
y = 200
M = np.float32([[1, 0, x], [0, 1, y]])
b = cv2.warpAffine(a, M, (height, width))
旋转:
height, width = a.shape[:2]
M = cv2.getRotationMatrix2D((height/2, width/2), 45, 0.6)
b = cv2.warpAffine(a, M, (height, width))
仿射变换:
rows, cols, ch = img.shape
p1 = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1]])
p2 = np.float32([[0, rows * 0.33], [cols * 0.85, rows * 0.25], [cols * 0.15, rows * 0.7]])
M = cv2.getAffineTransform(p1, p2)
dst = cv2.warpAffine(img, M, (cols, rows))
a = cv2.imread("image\\lena512.bmp", cv2.IMREAD_UNCHANGED)
# 注意原始图像的类型,必须是8位单通道图像,彩色图像无意义
r, b = cv2.threshold(a, 127, 255, cv2.THRESH_BINARY_INV)
阈值函数返回两个参数,前一个是阈值,后一个是处理后的图像
o = cv2.imread("image\\lenaNoise.png")
r = cv2.blur(o, (5, 5))
o = cv2.imread("image\\lenaNoise.png")
r = cv2.boxFilter(o, -1, (4, 4), normalize=1)
normalize = False or True,False 求和, True 求均值
归一化:均值
r = cv2.GaussianBlur(o, (3, 3), 0)
核大小为奇数,第三个参数控制x方向权重,参数为0时自动计算
o = cv2.imread("image\\lenaNoise.png")
r = cv2.medianBlur(o, 3)
k = np.ones((5, 5), np.uint8)
r = cv2.erode(o, k, iterations=10)
iteration:迭代次数
k = np.ones((5, 5), np.uint8)
r = cv2.dilate(o, k, iterations=1)
k = np.ones((5, 5), np.uint8)
r = cv2.morphologyEx(o, cv2.MORPH_OPEN, k)
先腐蚀,后膨胀
k = np.ones((5, 5), np.uint8)
r = cv2.morphologyEx(o, cv2.MORPH_CLOSE, k)
先膨胀,后腐蚀
k = np.ones((5, 5), np.uint8)
r = cv2.morphologyEx(o, cv2.MORPH_GRADIENT, k)
膨胀 - 腐蚀
k = np.ones((5, 5), np.uint8)
r = cv2.morphologyEx(o, cv2.MORPH_TOPHAT, k)
原图 - 开运算
k = np.ones((10, 10), np.uint8)
r = cv2.morphologyEx(o, cv2.MORPH_BLACKHAT, k)
闭运算 - 原图
x方向:
scharrx = cv2.Scharr(o, cv2.CV_64F, 1, 0)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8
y方向:
scharry = cv2.Scharr(o, cv2.CV_64F, 0, 1)
scharry = cv2.convertScaleAbs(scharry) # 转回uint8
xy方向:
scharrx = cv2.Scharr(o, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(o, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
x方向:
scharrx = cv2.Scharr(o, cv2.CV_64F, 1, 0, -1)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8
y方向:
scharry = cv2.Scharr(o, cv2.CV_64F, 0, 1, -1)
scharry = cv2.convertScaleAbs(scharry) # 转回uint8
xy方向:
scharrx = cv2.Scharr(o, cv2.CV_64F, 1, 0, -1)
scharry = cv2.Scharr(o, cv2.CV_64F, 0, 1, -1)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
scharr算子只要在sobel函数的末尾加上-1为参数即可转换,scharr算子是sobel算子的改进版
r = cv2.Canny(o, 150, 200)
两个参数为阈值,阈值越小,边界信息越丰富。
r = cv2.pyrDown(o)
图像减小为原图像的四分之一。
r = cv2.pyrUp(o)
图像增大四倍。
od = cv2.pyrDown(o)
odu = cv2.pyrUp(od)
lapPyr = o - odu
contours, hierarchy = cv2.findContours(image, mode, method)
image 原始图像
contours 轮廓 mode 轮廓检索模式
hierarchy 图像的拓扑信息 method 轮廓的近似方法
contours, hierarchy = cv2.findContours(image, mode, method)
mode:
cv2.RETR_EXTERNAL :表示只检测外轮廓
cv2.RETR_LIST :检测的轮廓不建立等级关系
cv2.RETR_CCOMP :建立两个等级的轮廓,上面的一层为外边界,里 面的一层为内孔的边界信息。如果内孔内还有 一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE :建立一个等级树结构的轮廓。
contours, hierarchy = cv2.findContours(image, mode, method)
method:
cv2.CHAIN_APPROX_NONE :存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y1-y2))==1
cv2.CHAIN_APPROX_SIMPLE :压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
cv2.CHAIN_APPROX_TC89_L1 :使用teh-Chinnl chain近似算法
cv2.CHAIN_APPROX_TC89_KCOS :使用teh-Chinl chain近似算法
r=cv2.drawContours(o,contours,contourldx,color[,thickness])
r :目标图像,直接修改目标的像素点,实现绘制
o :原始图像
contours :需要绘制的边缘数组。
contourldx:需要绘制的边缘索引,如果全部绘制则为-1
color :绘制的颜色,为BGR格式的Scalar。
thickness :可选,绘制的密度,即描绘轮廓时所用的画笔粗细。
新版本opencv,findContours返回两个参数,旧版本返回三个参数,分别是image, contours, hierarchy
需引入matplot.pyplot包:
m = plt.hist(o.ravel(), 256)
plt.show()
两个参数: 展开成一维数组,数字范围。
opencv:
hist = cv2.calcHist([img], [0], None, [256], [0, 255])
返回列表,256 * 1
y = sin(x)函数:
x = np.arange(0, 5, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.show()
色彩曲线:
a = [1, 2, 1, 2] # 仅有4个元素的列表
# 以红色曲线,显示列表的值
plt.plot(a, color='r')
plt.show()
y = f(x)集合对应:
x = [0, 0.5, 2, 3.5, 4, 4.3, 6]
y = [0.3, 0.4, 2, 5, 3, 4.5, 4]
plt.plot(x, y)
plt.show()
以整数为自变量:
y = [0.3, 0.4, 2, 5, 3, 4.5, 4]
plt.plot(y)
plt.show()
单色:
o = cv2.imread("image\\boatGray.bmp")
histb = cv2.calcHist([o], [0], None, [256], [0, 255])
plt.plot(histb, color='r')
plt.show()
彩色:
o = cv2.imread("image\\girl.bmp")
histb = cv2.calcHist([o], [0], None, [256], [0, 255])
histg = cv2.calcHist([o], [1], None, [256], [0, 255])
histr = cv2.calcHist([o], [2], None, [256], [0, 255])
plt.plot(histb, color='b')
plt.plot(histg, color='g')
plt.plot(histr, color='r')
plt.show()
image = cv2.imread("image\\girl.bmp", cv2.IMREAD_GRAYSCALE)
mask = np.zeros(image.shape, np.uint8)
mask[200:400, 200:400] = 255
histMI = cv2.calcHist([image], [0], mask, [256], [0, 255])
histImage = cv2.calcHist([image], [0], None, [256], [0, 255])
# hist直方图函数参数加[]
plt.plot(histImage)
plt.plot(histMI)
plt.show()
一个未mask,一个mask处理,两图的比较
mask = np.zeros(image.shape, np.uint8)
mask[200:400, 200:400] = 255
mi = cv2.bitwise_and(image, mask)
cv2.imshow('original', image)
cv2.imshow('mask', mask)
cv2.imshow('mi', mi)
figure函数使图像分开
函数:equalizeHist函数
plt.hist须将二维图像转化为一维数组,以下
img = cv2.imread('image\\equ.bmp', cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.hist(img.ravel(), 256)
plt.figure()
plt.hist(equ.ravel(), 256)
plt.show()
绘制两张直方图,分别表示均衡前后像素情况的对比,以下
o = cv2.imread("image\\equ.bmp", cv2.IMREAD_GRAYSCALE)
r = cv2.equalizeHist(o)
cv2.imshow("original", o)
cv2.imshow("result", r)
显示均衡化前后的两张图,以下
o = cv2.imread("image\\equ.bmp", cv2.IMREAD_GRAYSCALE)
r = cv2.equalizeHist(o)
cv2.imshow("original", o)
cv2.imshow("result", r)
cv2.waitKey()
cv2.destroyAllWindows()
img = cv2.imread('image\\equ.bmp', cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
#
plt.subplot(121), plt.hist(img.ravel(), 256)
plt.subplot(122), plt.hist(equ.ravel(), 256)
# subplot,当函数参数小于10的时候可以直接省去“,”
plt.show()
灰度图像:
o = cv2.imread('image\\girl.bmp')
g = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
#1
plt.subplot(221), plt.imshow(o), plt.axis('off')
#2
plt.subplot(222), plt.imshow(o, cmap=plt.cm.gray), plt.axis('off')
#3
plt.subplot(223), plt.imshow(g), plt.axis('off')
#4
plt.subplot(224), plt.imshow(g, cmap=plt.cm.gray), plt.axis('off')
#
plt.show()
彩色图像:
img = cv2.imread('image\\girl.bmp')
b, g, r = cv2.split(img)
img2 = cv2.merge([r, g, b])
#
plt.subplot(121), plt.imshow(img), plt.axis('off')
plt.subplot(122), plt.imshow(img2), plt.axis('off')
#
plt.show()
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
ishift = np.fft.ifftshift(dftShift)
iImg = cv2.idft(ishift)
iImg = cv2.magnitude(iImg[:, :, 0], iImg[:, :, 1])
两个通道分别转换
#
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
#
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)
fshift[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0
#
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
#
img = cv2.imread('image\\lena.bmp', 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)
mask = np.zeros((rows, cols, 2), np.uint8)
# 两个通道,与频谱图像匹配
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
fShift = dftShift * mask
ishift = np.fft.ifftshift(fShift)
iImg = cv2.idft(ishift)
iImg = cv2.magnitude(iImg[:, :, 0], iImg[:, :, 1])