OpenCV学习心得——python版——像素运算与图像常见的几何变换
FOR THE SIGMA
FOR THE GTINDER
FOR THE ROBOMASTER
本笔记仅供参考
操作系统版本:Windows10
编译器:JetBrains PyCharm 2019.1.3 x64
所需库:
opencv-python2.xx.xx以上
numpy
pillow
电子版书籍下载地址
暂无资源
前排提醒,两个源图像需要满足大小一样,否则会报错
两个图形像素加运算
#调用opencv中函数进行操作
import cv2 as cv
def add_demo(m1, m2):
dst = cv.add(m1, m2)
cv.imshow("add_demo", dst) #输出add后的图像(显示)
img1 = cv.imread("messigray.png") #灰度图-sss的
img2 = cv.imread("sss.jpg") #原图-sss的(彩色)
cv.imshow("messigray", img1)
cv.imshow("sss", img2)
add_demo(img1, img2)
cv.waitKey(0) #无限等待用户相应
cv.destroyAllWindows()
#调用numpy直接对像素点操作
import numpy as np
import cv2
x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y)) # 输出255
print(x + y) # 输出4,因为发生溢出
# 两张图像按权重进行相加融合
img1 = cv2.imread('messigray.png')
img2 = cv2.imread('sss.jpg')
# 注意两个图片需要相同的尺寸,否则无法进行相加或融合操作
img = cv2.addWeighted(img1, 0.3, img2, 0.7, 0) #前者权重0.3,后者0.7
# 其中最后一个0,表示两个图像相加后的常数值,这里设置为0
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
两个图形像素减运算
import cv2 as cv
def subtract_demo(m1, m2):
dst = cv.subtract(m1, m2)
cv.imshow("substract_demo",dst) #输出substract后的图像(显示)
img1 = cv.imread("messigray.png") #灰度图-sss的
img2 = cv.imread("sss.jpg") #原图-sss的(彩色)
cv.imshow("messigray", img1)
cv.imshow("sss", img2)
subtract_demo(img1, img2)
cv.waitKey(0) #无限等待用户相应
cv.destroyAllWindows()
两个图形像素除运算
注意在除法时注意被除数与除数之间的关系,结果为负值则图像以黑色显示(全0)
import cv2 as cv
def divide_demo(m1, m2):
dst = cv.divide(m1, m2)
cv.imshow("divide_demo",dst) #输出divide后的图像(显示)
img1 = cv.imread("messigray.png") #灰度图-sss的
img2 = cv.imread("sss.jpg") #原图-sss的(彩色)
cv.imshow("messigray", img1)
cv.imshow("sss", img2)
divide_demo(img1, img2)
cv.waitKey(0) #无限等待用户相应
cv.destroyAllWindows()
两个图像的乘运算
import cv2 as cv
def multiply_demo(m1, m2):
dst = cv.multiply(m1, m2)
cv.imshow("multiply_demo",dst) #输出multiply后的图像(显示)
img1 = cv.imread("messigray.png") #灰度图-sss的
img2 = cv.imread("sss.jpg") #原图-sss的(彩色)
cv.imshow("messigray", img1)
cv.imshow("sss", img2)
multiply_demo(img1, img2)
cv.waitKey(0) #无限等待用户相应
cv.destroyAllWindows()
总结
#像素的算术运算(加、减、乘、除)
import cv2 as cv
def add_demo(m1, m2): #像素的加运算
dst = cv.add(m1, m2)
cv.imshow("add_demo", dst)
def subtract_demo(m1, m2): #像素的减运算
dst = cv.subtract(m1, m2)
cv.imshow("subtract_demo", dst)
def divide_demo(m1, m2): #像素的除法运算
dst = cv.divide(m1, m2)
cv.imshow("divide_demo", dst)
def multiply_demo(m1, m2): #像素的乘法运算
dst = cv.multiply(m1, m2)
cv.imshow("multiply_demo", dst)
img1 = cv.imread('messigray.png')
img2 = cv.imread('sss.jpg')
cv.imshow('image1', img1)
cv.imshow('image2', img2)
add_demo(img1, img2)
subtract_demo(img1, img2)
divide_demo(img1, img2)
multiply_demo(img1, img2)
cv.waitKey(0)
cv.destroyAllWindows()
位运算
像素的逻辑运算涉及与、或、非、异或等基本运算,图像大小需要一样
import cv2 as cv
def and_demo(m1, m2): #与运算 每个像素点每个通道的值按位与
dst = cv.bitwise_and(m1, m2)
cv.imshow("and_demo", dst)
def or_demo(m1, m2): #或运算 每个像素点每个通道的值按位或
dst = cv.bitwise_or(m1, m2)
cv.imshow("or_demo", dst)
def not_demo(m1): #非运算 每个像素点每个通道的值按位取反
dst = cv.bitwise_not(m1)
cv.imshow("not_demo", dst)
def xor_demo(m1,m2): #异或运算 相同取0,相反取1
dst = cv.bitwise_xor(m1, m2)
cv.imshow("xor_demo", dst)
img1 = cv.imread('messigray.png')
img2 = cv.imread('sss.jpg')
cv.imshow('image1', img1)
cv.imshow('image2', img2)
and_demo(img1, img2)
or_demo(img1, img2)
not_demo(img1)
xor_demo(img1,img2)
cv.waitKey(0)
cv.destroyAllWindows()
对比度与亮度
import cv2 as cv
import numpy as np
def contrast_brightness_image(img1, ratio, b):
h, w, ch = img1.shape
img2 = np.zeros([h, w, ch], img1.dtype) # 新建的一张全黑图片和img1图片shape类型一样,元素类型也一样
dst = cv.addWeighted(img1, ratio, img2, 1 - ratio, b)
cv.imshow("csecond", dst)
src = cv.imread("sss.jpg")
cv.imshow("first", src)
contrast_brightness_image(src, 0.1, 10) #第2个参数rario为对比度 第3个参数b为亮度
cv.waitKey(0)
cv.destroyAllWindows()
OpenCV 提供了两个变换函数,cv2.warpAffine 和 cv2.warpPerspective,使用这两个函数你可以实现所有类型的变换。cv2.warpAffine 接收的参数是2 × 3 的变换矩阵,而 cv2.warpPerspective 接收的参数是 3 × 3 的变换矩阵。
一:仿射变换(平移,缩放,旋转等)
1、缩放
将图像放大,缩小,其根本就是让Sx和Sy取不同的值,对x缩放就是让Sx取不同的值,对y缩放就是让Sy取不同的值
import cv2
import numpy as np
image = cv2.imread('sss.jpg')
h, w = image.shape[:2] #高,宽(取前两个)
A1 = np.array([[0.5, 0, 0], [0, 0.5, 0]], np.float32) # 相当于长宽都变为原来的1/2
d1 = cv2.warpAffine(image, A1, (w, h), borderValue=0) #上面125是指定多余空间的像素值
cv2.imshow('img1', d1)
cv2.waitKey(0)
cv2.destroyAllWindows()
另一种方法:
import cv2
import numpy as np
img=cv2.imread('sss.jpg')
res=cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC) # 下面的 None 本应该是输出图像的尺寸,但因为后边我们设置了缩放因子
height,width=img.shape[:2]
res=cv2.resize(img,(2*width,2*height),interpolation=cv2.INTER_CUBIC)
while(1):
cv2.imshow('res',res)
cv2.imshow('img',img)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
# Resize(src, dst, interpolation=CV_INTER_LINEAR)
2、平移
平移就是将对象换一个位置。如果你要沿(x,y)方向移动,移动的距离是(tx ,ty ),而tx, ty取不同的值,可以让x和y坐标进行不同程度的偏移。可以使用 Numpy 数组构建这个矩阵(数据类型是 np.float32),然后把它传给函数 cv2.warpAffine()。
import cv2
import numpy as np
image = cv2.imread('sss.jpg')
h, w = image.shape[:2] #高,宽(取前两个)
# 先缩小两倍,在平移
A2 = np.array([[0.5, 0, w/4], [0, 0.5, h/4]], np.float32)
d2 = cv2.warpAffine(image, A2, (w, h), borderValue=0)
cv2.imshow('img2', d2)
cv2.waitKey(0)
另一种方法:
import cv2
import numpy as np
img = cv2.imread('sss.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]]) #移动了(100,50)个像素
dst = cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
需要注意的是:函数 cv2.warpAffine() 的第三个参数的是输出图像的大小,它的格式应该是图像的(宽,高)。应该记住的是图像的宽对应的是列数,高对应的是行数。
import cv2
import numpy as np
image = cv2.imread('sss.jpg')
h, w = image.shape[:2] #高,宽(取前两个)
A2 = np.array([[0.5, 0, w/4], [0, 0.5, h/4]], np.float32)
d2 = cv2.warpAffine(image, A2, (w, h), borderValue=125)
# 在d2的基础上绕中心点做旋转
A3 = cv2.getRotationMatrix2D((w/2.0, h/2.0), 30, 1)
d3 = cv2.warpAffine(d2, A3, (w, h), borderValue=125)
cv2.imshow('img3', d3)
cv2.waitKey(0)
cv2.destroyAllWindows()
另一种方法:
import cv2
import numpy as np
img=cv2.imread('sss.jpg',0)
rows,cols=img.shape
M=cv2.getRotationMatrix2D((cols/2,rows/2),45,0.6) #第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
dst=cv2.warpAffine(img,M,(2*cols,2*rows))# 第三个参数是输出图像的尺寸中心
while(1):
cv2.imshow('img',dst)
if cv2.waitKey(1)&0xFF==27:
break
cv2.destroyAllWindows()