*注:在此笔记中只记录下各种函数的使用,规则
详细讲解见https://opencv.apachecn.org/#/docs/4.0.0/2.1-tutorial_py_image_display
import numpy as np
img = np.zeros((512,512,3),np.uint8) # 创建一个图像 ,3 是指三个通道,可传入RGB
cv2.imread(“本工作目录下的文件名”,-1或0或1) # -1:加载图像,包括alpha通道,0:灰色模式加载图像,1:默认正常模式加载
cv.imshow('image', img) # imshow("窗口名字",要显示的图像)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey() 是一个键盘绑定函数,它的参数是以毫秒为单位的时间。该函数为任意键盘事件等待指定毫秒。如果你在这段时间内按下任意键,程序将继续。如果传的是 0,它会一直等待键盘按下。它也可以设置检测特定的击键,例如,按下键 a 等,我们将在下面讨论。
Note
除了绑定键盘事件,该函数还会处理许多其他 GUI 事件,因此你必须用它来实际显示图像。
cv.destroyAllWindows() 简单的销毁我们创建的所有窗口。如果你想销毁任意指定窗口,应该使用函数 cv.destroyWindow() 参数是确切的窗口名。
eg.下面的程序以灰度模式读取图像,显示图像,如果你按下 's‘ 会保存和退出图像,或者按下 ESC 退出不保存。
import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',0)
cv.imshow('image',img)
k = cv.waitKey(0)
if k == 27: # ESC 退出
cv.destroyAllWindows()
elif k == ord('s'): # 's' 保存退出
cv.imwrite('messigray.png',img)
cv.destroyAllWindows()
Note
有一种特殊情况,你可以先创建一个窗口然后加载图像到该窗口。在这种情况下,你能指定窗口是否可调整大小。它是由这个函数完成的 cv.namedWindow()。默认情况下,flag 是 cv.WINDOW_AUTOSIZE。但如果你指定了 flag 为 cv.WINDOW_NORMAL,你能调整窗口大小。当图像尺寸太大,在窗口中添加跟踪条是很有用的。
看下面的代码:
cv.namedWindow('image', cv.WINDOW_NORMAL)
cv.imshow('image',img)
cv.waitKey(0)
cv.destroyAllWindows()
保存图像,用这个函数 cv.imwrite()。
第一个参数是文件名,第二个参数是你要保存的图像。
cv.imwrite('messigray.png',img)
将该图像用 PNG 格式保存在工作目录。
Matplotlib 是一个 Python 的绘图库,提供了丰富多样的绘图函数。你将在接下来的文章中看到它们。在这里,你将学习如何使用 Matplotlib 来显示图像。你还能用 Matplotlib 缩放图像,保存图像等。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic') # 让图像以灰色形式展示
# 或者选择 plt.imshow(img[:,:,::-1]) #这一步操作,保证和原图像显示的色彩一致
plt.xticks([]), plt.yticks([]) # 隐藏 X 和 Y 轴的刻度值 去掉则会显示刻度
plt.show()
色彩模式与cv2不一样(BGR),因此显示出来的颜色不对,需要改一下
plt.imshow(img[:,:,::-1]) #这一步操作,保证和原图像显示的色彩一致
plt.show()
去画一条线,你需要传递线条的开始和结束的坐标。我们将创建一个黑色图像,并在坐上角到右下角画一条蓝色的线
import numpy as np
import cv2 as cv
# 创建一个黑色的图像
img = np.zeros((512,512,3), np.uint8)
# 画一条 5px 宽的蓝色对角线
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv2.line(图像,(起始坐标),(终点坐标),(颜色),宽度)
画一个圆,你需要它的圆心和半径。我们将在上面绘制的矩形上画一个内圆。
cv.circle(img,(447,63), 63, (0,0,255), -1)
cv.circle(图像,(圆心坐标x,y),半径,(颜色),加载方式)
画一个椭圆,你需要传好几个参数。一个参数是圆心位置 (x,y)。下个参数是轴的长度 (长轴长度,短轴长度)。角度是椭圆在你逆时针方向的旋转角度。startAngle 和 endAngle 表示从长轴顺时针方向测量的椭圆弧的起点和终点。如整圆就传 0 和 360。更多细节请看 cv.ellipse() 的文档。下面是在这个图像中间画的一个半椭圆例子。
cv.ellipse(img,(256,256),(100,50),0,0,180,(0,255,255),-1)
cv.ellipse(图像,(圆心坐标),(长轴,短轴),起时角度,起点,终点,颜色,加载方式
cv.rectangle(img,左上角坐标,右下角坐标,颜色,线条厚度)
画多边形,首先你需要顶点的做坐标。将这些点组成一个形状为 ROWSx1x2 的数组,ROWS 是顶点数,它应该是 int32 类型。这里我们绘制一个顶点是黄色的小多边形。
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))
Note
cv.putText(img,输入内容,文本的放置位置,字体,字体大小,颜色,线条宽度,cv.LINE__AA)
通过行列坐标来进行访问及修改
黄色为绿色和红色的混合。所以,该图像的所有像素值都应为R=255,G=255,B=0。
>>> import numpy as np
>>> import CV2
>>> img = CV2.imread("img/yellow.jpg")
>>> h,w,c = img.shape
#图像大小为128*128*3
>>> print(h,w,c)
128 128 3
px = img[100,100] # 获取某个点的像素值
从上面的代码中可以看到,您可以通过行和列坐标访问像素值。注意,对于常见的RGB 图像,OpenCV的imread函数返回的是一个蓝色(Blue)值、绿色(Green)值、红色(Red)值的数组,维度大小为3。而对于灰度图像,仅返回相应的灰度值。
>>> img[100,100]
#OpenCV的读取顺序为B,G,R,由于图像所有像素为黄色,因此,G=255,R=255
array([ 0, 255, 255], dtype=uint8)
# 仅访问蓝色通道的像素
>>> blue = img[100,100,0]
>>> print(blue)
0
你也可以使用同样的方法来修改像素值。
>>> img[100,100] = [255,255,255]
>>> print(img[100,100])
[255 255 255]
img.shape # 变量.shape
(256,256,3)
img.shape[:2] 取彩色图片的长、宽。
cols,rows = img.shape[:2]
# 或者
cols,rows,x = img.shape
使用灰色模式
cols ,rows = img.shape
如果img.shape[:3] 则取彩色图片的长、宽、通道。
关于img.shape[0]、[1]、[2]
img.shape[0]:图像的垂直尺寸(高度)
img.shape[1]:图像的水平尺寸(宽度)
img.shape[2]:图像的通道数
img.dtype
dtype('uint8')
img.size
196608
一、图像缩放
图像缩放主要使用resize函数
result = cv2.resize(src, dsize[, result[. fx[, fy[, interpolation]]]]) 记得要用新变量来接收
其中src表示原始图像,dsize表示缩放大小,fx和fy也可以表示缩放大小倍数,他们两个(dsize或fx\fy)设置一个即可实现图像缩放
参数说明:
src - 原图
dst - 目标图像。当参数dsize不为0时,dst的大小为size;否则,它的大小需要根据src的大小,参数fx和fy决定。dst的类型(type)和src图像相同
dsize - 目标图像大小。当dsize为0时,它可以通过以下公式计算得出:
所以,参数dsize和参数(fx, fy)不能够同时为0
fx - 水平轴上的比例因子。当它为0时,计算公式如下:
fy - 垂直轴上的比例因子。当它为0时,计算公式如下:
interpolation - 插值方法。共有5种:
INTER_NEAREST - 最近邻插值法
INTER_LINEAR - 双线性插值法(默认)
INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取也叫缩小图像(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
INTER_CUBIC - 基于4x4像素邻域的3次插值法
INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
缩小图像 用INTER_AREA更好,放大图像用 INTER_CUBIC更好;
————————————————
代码如下:
import cv2
#读取图片
image = cv2.imread("E:/pythonProject/xin.jpeg")
#图片缩放
image1 = cv2.resize(image, (200,200))
#图片显示
cv2.imshow("resize", image1)
cv2.imshow("image", image)
#等待窗口
cv2.waitKey(0)
opencv中对图像的旋转主要是先通过getRotationMatrix2D函数得到图像的旋转矩阵,然后再通过仿射变换函数warpAffine得到旋转后的图像。
函数说明:
cv2.getRotationMatrix2D(center, angle, scale)
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
参数说明:
getRotationMatrix2D: 得到图像的旋转矩阵
center–表示旋转的中心点
angle–表示旋转的角度degrees
scale–图像缩放因子
warpAffine:
src – 输入的图像
M – 2 X 3 的变换矩阵.
dsize – 输出的图像的size大小
dst – 输出的图像
flags – 输出图像的插值方法
borderMode – 图像边界的处理方式
borderValue – 当图像边界处理方式为BORDER_CONSTANT 时的填充值
代码示范:
img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
#90度旋转
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img,M,(cols,rows))
代码示范:
img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
# 平移矩阵M:[[1,0,x],[0,1,y]]
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))
函数说明:
cv2.flip(src, flipCode[, dst]) → dst
1
参数说明:
src – 输入的图像
dst – 输出的图像
flipCode – 翻转模式,flipCode==0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)
代码示范:
# 水平翻转
flip_horiz_img = cv2.flip(pad_img, 1)
# 垂直翻转
flip_verti_img = cv2.flip(pad_img, 0)
# 水平垂直翻转
flip_horandver_img = cv2.flip(pad_img, -1)
单个图像多次拼接
import cv2
img =cv2.imread(file_path[i])
img=cv2.hconcat([img,img,img])#水平拼接
img=cv2.vconcat([img,img,img])#垂直拼接
多个相似特征图像拼接(开摆!)
import cv2
import numpy as np
def stitch(image):
# 图像拼接
# stitcher = cv2.createStitcher(False) # OpenCV 3.X.X.X使用该方法
stitcher = cv2.Stitcher_create(cv2.Stitcher_PANORAMA) # OpenCV 4.X.X.X使用该方法,cv2.Stitcher_create()也可以
status, pano = stitcher.stitch(image)
# 黑边处理
if status == cv2.Stitcher_OK:
# 全景图轮廓提取
stitched = cv2.copyMakeBorder(pano, 10, 10, 10, 10, cv2.BORDER_CONSTANT, (0, 0, 0))
gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
# 轮廓最小正矩形
mask = np.zeros(thresh.shape, dtype="uint8")
(x, y, w, h) = cv2.boundingRect(cnts[0]) # 取出list中的轮廓二值图,类型为numpy.ndarray
cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)
# 腐蚀处理,直到minRect的像素值都为0
minRect = mask.copy()
sub = mask.copy()
while cv2.countNonZero(sub) > 0:
minRect = cv2.erode(minRect, None)
sub = cv2.subtract(minRect, thresh)
# 提取minRect轮廓并裁剪
cnts = cv2.findContours(minRect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
(x, y, w, h) = cv2.boundingRect(cnts[0])
stitched = stitched[y:y + h, x:x + w]
cv2.imshow('stitched', stitched)
cv2.imwrite('stitched.jpg', stitched)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print('图像匹配的特征点不足')
if __name__ == "__main__":
image1 = cv2.imread('data/space1.jpg')
image2 = cv2.imread('data/space2.jpg')
image3 = cv2.imread('data/space3.jpg')
image = image1, image2, image3
stitch(image)
(18条消息) OpenCV-Python 图像全景拼接stitch及黑边处理_Klein-的博客-CSDN博客_stitcher_create