1.ROI 选取
import cv2
img = cv2.imread('lena.jpg')
# 帽子ROI的红色通道
hat_r = img[25:120, 50:220, 2]
cv2.imshow('hat', hat_r)
cv2.waitKey(0)
2.图像和像素点的简单处理
import cv2
img = cv2.imread('lena.jpg')
# 1.获取像素的值
px = img[100, 90]
print(px) # [103 98 197]
# 只获取蓝色blue通道的值
px_blue = img[100, 90, 0]
print(px_blue) # 103
# 2.修改像素的值
img[100, 90] = [255, 255, 255]
print(img[100, 90]) # [255 255 255]
# 3.图片形状
print(img.shape) # (263, 247, 3)
# 形状中包括行数、列数和通道数
height, width, channels = img.shape
# img是灰度图的话:height, width = img.shape
# 总像素数
print(img.size) # 263*247*3=194883
# 数据类型
print(img.dtype) # uint8
# 4.ROI截取
face = img[100:200, 115:188]
cv2.imshow('face', face)
cv2.waitKey(0)
# 5.通道分割与合并
b, g, r = cv2.split(img)
img = cv2.merge((b, g, r))
# 更推荐的获取某一通道方式
b = img[:, :, 0]
cv2.imshow('b', b)
cv2.waitKey(0)
3.改变色彩空间
import cv2
import numpy as np
img=cv2.imread('lena.jpg')
#转灰度图片
img_hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow('hsv',img_hsv)
cv2.waitKey(0)
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',img_gray)
cv2.waitKey(0)
#获取所有转换模式
flags=[i for i in dir(cv2) if i.startswith("COLOR_")]
print(flags)
#获取蓝色的HSV
blue =np.uint8([[[255,0,0]]])
hsv_blue = cv2.cvtColor(blue,cv2.COLOR_BGR2HSV)
print(hsv_blue)
#追踪蓝色的物体
capature =cv2.VideoCapture(0)
#蓝色范围
blue_lower =np.array([100,110,110])
blue_upper = np.array([130,255,255])
while(True):
ret,frame= capature.read()
gray2=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
# 又BGR 转换为HSV
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
#将hsv设置为介于两者之间的
mask = cv2.inRange(hsv,blue_lower,blue_upper)
#只保留图片中的蓝色部分
res = cv2.bitwise_and(frame,frame,mask=mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
cv2.imshow('gary',gray2)
if cv2.waitKey(1) == ord('q'):
break
4.对图像进行阈值操作
import cv2 as cv
import matplotlib.pyplot as plt
#灰度图片读入
img = cv.imread('gradient.jpg',0)
'''filename:需要打开图片的路径,可以是绝对路径或者相对路径,路径中不能出现中文。
flag:图像的通道和色彩信息(默认值为1)。
flag = -1, 8位深度,原通道
flag = 0, 8位深度,1通道
flag = 1, 8位深度,3通道
flag = 2, 原深度, 1通道
flag = 3, 原深度, 3通道
flag = 4, 8位深度,3通道'''
#阈值分割,ret return value 表示当前阈值
ret,th =cv.threshold(img,127,255,cv.THRESH_BINARY)
'''cv2.threshold(img, thresh, maxVal, cv2.xxx)
1
第一个参数是源图像,应该是灰度图;
第二个参数是对图像进行分类的阈值;
第三个参数是最大值,表示如果像素值大于(有时小于)阈值则要给出的值;
第四个参数决定给出不同类型的阈值。包括:
cv2.THRESH_BINARY
- cv2.THRESH_BINARY_INV
- cv2.THRESH_TRUNC
- cv2.THRESH_TOZERO
- cv2.THRESH_TOZERO_INV'''
#图像二值化处理后
cv.imshow('thresh',th)
#未经过二值化处理的图片
cv.imshow('org',img)
cv.waitKey(0)
# 应用5种不同的阈值方法
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret, th2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
ret, th3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
ret, th4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
ret, th5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
titles = ['Original', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, th1, th2, th3, th4, th5]
for i in range(6):
plt.subplot(2, 3, i + 1)
plt.imshow(images[i], 'gray')
plt.title(titles[i], fontsize=8)
plt.xticks([]), plt.yticks([]) # 隐藏坐标轴
plt.show()
#自适应阈值对比固定阈值
#固定阈值
ret,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
#自适应阈值
th2=cv.adaptiveThreshold(
img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,11,4
)
th3=cv.adaptiveThreshold(
img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,17,6
)
titles = ['Original', 'Global(v = 127)', 'Adaptive Mean', 'Adaptive Gaussian']
images = [img, th1, th2, th3]
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.imshow(images[i], 'gray')
plt.title(titles[i], fontsize=8)
plt.xticks([]), plt.yticks([])
plt.show()
5.图片几何化处理
import numpy as np
import cv2
img= cv2.imread('drawing.jpg')
#1将图片进行缩放
res=cv2.resize(img,(132,150))
cv2.imshow('reshape',res)
cv2.imshow('org',img)
#2按照比例进行缩放,x,y轴都扩大为原来的两倍
res2=cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_LINEAR)
cv2.imshow('res2',res2)
cv2.waitKey(0)
'''cv2.resize(src,dsize,dst=None,fx=None,fy=None,interpolation=None)
scr:原图
dsize:输出图像尺寸
fx:沿水平轴的比例因子
fy:沿垂直轴的比例因子
interpolation:插值方法'''
#3.翻转图片
dst=cv2.flip(img,-1) #1 水平翻转 0 垂直翻转 -1 水平垂直翻转
#np.hstack 横向并排,对比显示
cv2.imshow('flip',np.hstack((img,dst)))
cv2.waitKey(0)
#4.平移图片
#得到图片的长和宽的像素
rows,cols= img.shape[:2]
M = np.float32([[1, 0, 100], [0, 1, 50]])#M 为一个2x3的矩阵 (为图片的变化矩阵)
'''src - 输入图像。
M - 变换矩阵。
dsize - 输出图像的大小。
flags - 插值方法的组合(int 类型!)
borderMode - 边界像素模式(int 类型!)
borderValue - (重点!)边界填充值; 默认情况下,它为0。
上述参数中:
1、M作为仿射变换矩阵,一般反映平移或旋转的关系,为InputArray类型的2×3的变换矩阵。
2、flages表示插值方式,默认为 flags=cv2.INTER_LINEAR,表示线性插值,此外还有:cv2.INTER_NEAREST(最近邻插值) cv2.INTER_AREA (区域插值) cv2.INTER_CUBIC(三次样条插值) cv2.INTER_LANCZOS4(Lanczos插值)'''
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('shift', dst)
cv2.waitKey(0)
#5.将图片顺时针旋转,并且缩小一半
M=cv2.getRotationMatrix2D((cols/2,rows/2),-45,0.5)
'''M=cv2.getRotationMatrix2D(center, angle, scale)
1
函数有三个输入参数:
center:图片的旋转中心
angle:旋转角度
scale:旋转后图像相比原来的缩放比例
M:计算得到的旋转矩阵'''
dst=cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('rotation',dst)
cv2.waitKey(0)
6.图形绘制
import cv2
import numpy as np
#创建一个黑色图片
img =np.zeros((512,512,3),np.uint8)
#创建一条宽度为5的蓝色斜线 参数起点 终点
cv2.line(img,(0,0),(512,512),5)
#画一个绿色边框的矩形,参数 左上角,右下角
cv2.rectangle(img,(300,0),(500,100),(0,255,0),3)
#画一个填充红色的圆,参数 圆心坐标,半径
cv2.circle(img,(447,63),63,(255,0,0),-1)
# 4.在图中心画一个填充的半圆
cv2.ellipse(img, (256, 256), (100, 50), 0, 0, 180, (255, 0, 0), -1)
# 5.画一个闭合的四边形
# 定义四个顶点坐标
pts = np.array([[10, 5], [50, 10], [70, 20], [20, 30]], np.int32)
# 顶点个数:4,矩阵变成顶点数*1*2维(注意numpy中-1的用法)
pts = pts.reshape((-1, 1, 2))
cv2.polylines(img, [pts], True, (0, 255, 255))
# 使用cv2.polylines()画多条直线
line1 = np.array([[100, 20], [300, 20]], np.int32).reshape((-1, 1, 2))
line2 = np.array([[100, 60], [300, 60]], np.int32).reshape((-1, 1, 2))
line3 = np.array([[100, 100], [300, 100]], np.int32).reshape((-1, 1, 2))
cv2.polylines(img, [line1, line2, line3], True, (0, 255, 255))
# 6.添加文字
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, 'ex2tron', (10, 500), font,
4, (255, 255, 255), 2, lineType=cv2.LINE_AA)
cv2.imshow('img', img)
cv2.waitKey(0)
7.图形融合
import cv2
import numpy as np
#1.图片相加
x = np.uint8([255])
y = np.uint8([10])
print(cv2.add(x,y))# 250+10 = 260 => 255 超过了255按照255算 没有超过255 按计算值算
print(x+y)# 250+10 = 260 % 256 = 4 numpy 中的图片相加相当于%256
#2.图像混合
img1=cv2.imread('lena_small.jpg')
img2=cv2.imread('opencv-logo-white.png')
res=cv2.addWeighted(img1,.6,img2,.4,0)
cv2.imshow('blending',res)
cv2.waitKey(0)
#3.按位操作
img1=cv2.imread('lena.jpg')
img2=cv2.imread('opencv-logo-white.png')
#把logo放在左上角
rows,cows=img2.shape[:2]
roi=img1[:rows,:cows]
#创建掩膜
img2gray=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret,mask =cv2.threshold(img2gray,10,255,cv2.THRESH_BINARY)
mask_inv=cv2.bitwise_not(mask)
# 保留除logo外的背景
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
dst = cv2.add(img1_bg, img2) # 进行融合
img1[:rows, :cows] = dst # 融合后放在原图上
cv2.imshow('result', img1)
cv2.waitKey(0)
8.图片滤波
import cv2
import numpy as np
img=cv2.imread('lena.jpg')
#1.均值滤波
blur=cv2.blur(img,(12,12))#卷积核尺寸 可以明显观察到经过滤波后的图片模糊很多
cv2.imshow('img',img)
cv2.imshow('blur',blur)
cv2.waitKey(0)
#2.高斯滤波
gau_blur=cv2.GaussianBlur(img,(3,3),0)#(3,3)表示高斯矩阵的长和宽都是5,标准差为0
#三张图片横向对比
res = np.hstack((img,blur,gau_blur))
cv2.imshow('res',res)
cv2.waitKey(0)
#高斯滤波与均值滤波
img=cv2.imread('salt_noise.bmp')
blur=cv2.blur(img,(5,5)) #均值滤波
gaussian = cv2.GaussianBlur(img,(5,5),1) #高斯滤波
res = np.hstack((img,blur,gaussian))
cv2.imshow('img,blur,gaussian',res)
cv2.waitKey(0)
#均值滤波与中值滤波
img=cv2.imread('salt_noise.bmp',0)
blur = cv2.blur(img, (5, 5)) # 均值滤波
median = cv2.medianBlur(img, 5) # 中值滤波
res = np.hstack((img, blur, median))
cv2.imshow('median vs average', res)
cv2.waitKey(0)
# 4.双边滤波vs高斯滤波
img = cv2.imread('lena.jpg', 0)
gau = cv2.GaussianBlur(img, (5, 5), 0) # 高斯滤波
blur = cv2.bilateralFilter(img, 5, 75, 75) # 双边滤波
res = np.hstack((img, gau, blur))
cv2.imshow('res', res)
cv2.waitKey(0)
9.边缘检测1
import cv2
import numpy as np
#边缘检测
img = cv2.imread('handwriting.jpg',0)
edges =cv2.Canny(img,30,70)
cv2.imshow('img_edges',np.hstack((img,edges)))
cv2.waitKey(0)
#2.先阈值后边缘检测
_,thresh =cv2.threshold(img,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
edges = cv2.Canny(thresh,30,70)
cv2.imshow('canny',np.hstack((img,thresh,edges)))
cv2.waitKey(0)
10.边缘检测2
import cv2
import numpy as np
def track_back(x):
pass
img =cv2.imread('sudoku.jpg',0)
cv2.namedWindow('window')
#创建滑动条
cv2.createTrackbar('maxVal','window',100,255,track_back)
cv2.createTrackbar('minVal','window',200,255,track_back)
while(True):
#获取滑动条的值
max_val=cv2.getTrackbarPos('maxVal','window')
min_val=cv2.getTrackbarPos('minVal','window')
edges= cv2.Canny(img,min_val,max_val)
cv2.imshow('window',edges)
if cv2.waitKey(30)==27:
break
11.腐蚀和膨胀处理
import cv2
import numpy as np
#1.腐蚀和膨胀
img = cv2.imread('j.bmp',0)
kernel =np.ones((5,5),np.uint8)
erosion =cv2.erode(img,kernel)#腐蚀
dilation = cv2.dilate(img,kernel) #膨胀
cv2.imshow('erosion/dilation',np.hstack((img,erosion,dilation)))
cv2.waitKey(0)