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)