一,图像的基础操作
1.1 获取并修改像素值
import cv2
import os
imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")
image = cv2.imread(imagePath)
px = image[100,100]
print(px)
image[100,100,2] = 100
px = image[100,100,2]
print(px)
print(image.item(10,10,2))
image.itemset((10,10,2),100) # 更改像素值这种方法比使用上面的矩阵方式更快。
print(image.item(10,10,2))
print(image.shape)
print(image.size)
输出结果如下:
[0 0 0]
100
0
100
(732, 861, 3)
1890756
1.2 获取图像数据类型
import cv2
import os
imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")
image = cv2.imread(imagePath)
print(image.dtype) #返回图像数据类型
print(image.shape) #返回行,列,通道组成的元祖
"""
#通用代码获取图像 H ,W ,不用管是彩色图像还是黑白图像
"""
imgH,imgW = image.shape[:2]
print(imgH,imgW)
print(image.size) #返回图像的像素数目
输出结果如下:
uint8
(732, 861, 3)
732 861
1890756
1.3 图像ROI区域
import cv2
import os
import copy
from matplotlib import pyplot as plt
imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")
image = cv2.imread(imagePath)
imageTemp = copy.deepcopy(image)
ball = imageTemp[400:450,400:450]
imageTemp[400:450,610:660] = ball #在宽度方向进行覆盖,注意切片的大小必须一样
plt.subplot(121),plt.imshow(image,'gray'),plt.title('ORIGINAL')
plt.subplot(122),plt.imshow(imageTemp,'gray'),plt.title('CHANGE')
plt.show()
输出结果如下:
1.4 拆分和合并图像通道
import cv2
import os
from matplotlib import pyplot as plt
imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")
image = cv2.imread(imagePath)
"""
#拆分 图像的通道 ,非常耗时,能不使用最好不要使用。
opencv 读出来的图像默认是按照 B G R 通道的排序
"""
B,G,R = cv2.split(image)
"""
#使用numpy 索引比 cv2.split 速度快
"""
B = image[:,:,0]
G = image[:,:,1]
R = image[:,:,2]
imageTemp = cv2.merge((R,G,B)) # 合并图像通道
imageTemp1 = cv2.merge((G,B,R)) # 合并图像通道
plt.subplot(221),plt.imshow(image,'gray'),plt.title('ORIGINAL')
plt.subplot(222),plt.imshow(imageTemp,'gray'),plt.title('CHANGE')
plt.subplot(223),plt.imshow(imageTemp1,'gray'),plt.title('CHANGE1')
plt.show()
输出结果如下:
1.5 为图像扩充边界
import cv2
import os
from matplotlib import pyplot as plt
BLUE = [255,0,0]
imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"OpenCVLogo.PNG")
image = cv2.imread(imagePath)
replicate = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_REFLECT)
reflect_101 = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(image,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect_101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
输出结果如下:
函数cv2.copyMakeBorder 介绍:
参考opencv 官方教程:Image Filtering — OpenCV 2.3.2 documentation
函数原型:
cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]]) → dst
Parameters: |
|
---|
borderType :
cv2.BORDER_CONSTANT 常数填充:|oooo|abcd|oooo|
cv2.BORDER_ISOLATED 使用黑色像素进行填充,同:cv2.BORDER_CONSTANT类型且value=0
cv2.BORDER_REFLECT 从外向内取图像边缘的像素填充:|dcba|abcd|dcba|
cv2.BORDER_REFLECT101 反射填充的另一种情况,跳过原图边上的一个像素值:|dcb|abcd|cba|
cv2.BORDER_REFLECT_101 同cv2.BORDER_REFLECT101
cv2.BORDER_DEFAULT 同cv2.BORDER_REFLECT101
cv2.BORDER_REPLICATE 复制图像最边上的像素进行填充:|aaaa|abcd|dddd|
cv2.BORDER_TRANSPARENT 这个类型在新的OpenCV4中已经被取消
cv2.BORDER_WRAP 在图像对侧从外向内取图像边缘的像素填充:|dcba|abcd|abcd|
二,图像算术运算
2.1 图像混合
import os
import numpy as np
# BLUE = [255,0,0]
imagePath1 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"OpenCVLogo.PNG")
imagePath2 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")
image1 = cv2.imread(imagePath1)
image2 = cv2.imread(imagePath2)
image2 = image2[50:image1.shape[0]+50,50:image1.shape[1]+50] #剪切出大小一样的图片
dst = cv2.addWeighted(image1,0.3,image2,0.7,0)
cv2.imshow("123",dst)
cv2.waitKey()
2.2 图像加法运算
import cv2
import os
import numpy as np
x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x,y)) # 250+10 = 260 => 255 OpenCV 有处理不会溢出
print(x+y) # 250+10 = 260 % 256 = 4 普通加法会溢出
"""
两幅图像加法最好使用OpenCV.add 方法 不会溢出
"""
结果如下:
[[255]]
[4]
2.3 按位运算
import cv2
import os
import numpy as np
from matplotlib import pyplot as plt
"""
这里包括的按位操作有:AND,OR,NOT,XOR 等
"""
imagePath2 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"OpenCVLogo.PNG")
imagePath1 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")
image1 = cv2.imread(imagePath1)
image2 = cv2.imread(imagePath2)
rows,cols,channels = image2.shape
roi = image1[0:rows,0:cols]
img2gray = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)
ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
img1_bg = cv2.bitwise_and(roi,roi,mask = mask)
img2_bg = cv2.bitwise_and(image2,image2,mask= mask_inv)
dst = cv2.add(img1_bg,img2_bg)
image1[0:rows,0:cols] = dst
plt.subplot(231),plt.imshow(image1[0:rows,0:cols],'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(img2gray,'gray'),plt.title('img2gray')
plt.subplot(233),plt.imshow(mask,'gray'),plt.title('mask')
plt.subplot(234),plt.imshow(mask_inv,'gray'),plt.title('mask_inv')
plt.subplot(235),plt.imshow(img1_bg,'gray'),plt.title('img1_bg')
plt.subplot(236),plt.imshow(img2_bg,'gray'),plt.title('img2_bg')
plt.show()
结果如下: