Opencv

1,HSV颜色空间

Hue:色调

Saturation:饱和度

Value:明亮度

 

2,opencv读取的是BGR,跟我们RGB有区别。需要做一个转换

# 读取图像将图像转换为Matplotlib可视化
# NOTE: 如果需要可视化图像,需要注意:OpenCV中是BGR图像,而Matplotlib中是RGB的图像。
img = cv.imread('t1.png', 1)
img2 = np.zeros_like(img, dtype=img.dtype)
img2[:, :, 0] = img[:, :, 2]
img2[:, :, 1] = img[:, :, 1]
img2[:, :, 2] = img[:, :, 0]
print(img2.shape)
plt.imshow(img2)
plt.show()

3,图像位运算

实际上x进行“非”操作,就是x->-x-1 

4,图像的基本处理:

读取,cv.imread('xiaoren.png', 0)

保存,cv.imwrite('t1.png', img)

可视化cv.imshow('image', img)

切割,合并b,g,r = cv.split(img)    img = cv.merge((r, g, b))

大小重置  dst = cv.resize(img, (new_width, new_height))

平移,旋转 cv.warpAffine(img,M,shape)通过构造有一个M矩阵来实现

图像模糊化

# 自定义一个kernel核
kernel = np.ones((3,3), np.float32) / 9

# 做一个卷积操作
# 第二个参数为:ddepth,一般为-1,表示不限制,默认值即可。
img2 = cv.filter2D(img, -1, kernel)

均值滤波 dst = cv.blur(img, ksize=(11,11))

高斯滤波 dst = cv.GaussianBlur(img, ksize=(9,9), sigmaX=2.0, sigmaY=2.0)

中值滤波  dst = cv.medianBlur(img, ksize=5)

双边滤波  dst = cv.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)

添加背景  

# 添加背景
# 计算公式:dst = alphe * src1 + beta * src2 + gamma
dst = cv.addWeighted(src1=img1, alpha=0.3, src2=img2, beta=1.0, gamma=0)

添加边框

replicate = cv.copyMakeBorder(img, top=10, bottom=10, left=10, right=10, borderType=cv.BORDER_REPLICATE)
# 边界反射
reflect = cv.copyMakeBorder(img,10,10,10,10,cv.BORDER_REFLECT)
# 边界反射,边界像素不保留
reflect101 = cv.copyMakeBorder(img,10,10,10,10,cv.BORDER_REFLECT_101)
# 边界延伸
wrap = cv.copyMakeBorder(img,10,10,10,10,cv.BORDER_WRAP)
# 添加常数
constant= cv.copyMakeBorder(img,10,10,10,10,cv.BORDER_CONSTANT, value=[128,128,128])

replicate

[1 1 1 1 2 3 3 3 3]

 [1 1 1 1 2 3 3 3 3]

 [1 1 1 1 2 3 3 3 3]

 [1 1 1 1 2 3 3 3 3]

 [4 4 4 4 5 6 6 6 6]

 [7 7 7 7 8 9 9 9 9]

 [7 7 7 7 8 9 9 9 9]

 [7 7 7 7 8 9 9 9 9]

 [7 7 7 7 8 9 9 9 9]]

reflect

[[9 8 7 7 8 9 9 8 7]

 [6 5 4 4 5 6 6 5 4]

 [3 2 1 1 2 3 3 2 1]

 [3 2 1 1 2 3 3 2 1]

 [6 5 4 4 5 6 6 5 4]

 [9 8 7 7 8 9 9 8 7]

 [9 8 7 7 8 9 9 8 7]

 [6 5 4 4 5 6 6 5 4]

 [3 2 1 1 2 3 3 2 1]]

reflect101

[[5 6 5 4 5 6 5 4 5]

 [8 9 8 7 8 9 8 7 8]

 [5 6 5 4 5 6 5 4 5]

 [2 3 2 1 2 3 2 1 2]

 [5 6 5 4 5 6 5 4 5]

 [8 9 8 7 8 9 8 7 8]

 [5 6 5 4 5 6 5 4 5]

 [2 3 2 1 2 3 2 1 2]

 [5 6 5 4 5 6 5 4 5]]

wrap

[[5 6 4 5 6 4 5]

 [8 9 7 8 9 7 8]

 [2 3 1 2 3 1 2]

 [5 6 4 5 6 4 5]

 [8 9 7 8 9 7 8]

 [2 3 1 2 3 1 2]

 [5 6 4 5 6 4 5]]

constant

[[0 0 0 0 0 0 0]

 [0 0 0 0 0 0 0]

 [0 0 1 2 3 0 0]

 [0 0 4 5 6 0 0]

 [0 0 7 8 9 0 0]

 [0 0 0 0 0 0 0]

 [0 0 0 0 0 0 0]]

 

 

5,基于opencv的基本绘画

cv.line画直线、cv.circle画圆、cv.rectangle画矩形、cv.ellipse画椭圆、cv.putText画文字等。常见参数

  • img:给定绘画的对象
  • color:给定像素点的颜色
  • thickness:给定线条粗细程度,-1表示填充图像
  • lineType:给定线条的类型

将logo放在图片右上角

import cv2 as cv
import matplotlib.pyplot as plt

# 图像的位运算(将logo放到图像的右上角)
# 加载图像
img1 = cv.imread("xiaoren.png")
img2 = cv.imread("opencv-logo.png")

# 获取一个新数据(右上角区域数据)
rows1, cols1, _ = img1.shape
rows, cols, channels = img2.shape
start_rows = 0
end_rows = rows
start_cols = cols1 - cols
end_cols = cols1
roi = img1[start_rows:end_rows, start_cols:end_cols]

# 将图像转换为灰度图像
img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
# 将灰度图像转换为黑白图像,做一个二值化操作
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
# 对图像做一个求反的操作,即255-mask
mask_inv = cv.bitwise_not(mask)

# 获取得到背景图(对应mask_inv为True的时候,进行and操作,其它位置直接设置为0)
# 在求解bitwise_and操作的时候,如果给定mask的时候,只对mask中对应为1的位置进行and操作,其它位置直接设置为0
img1_bg = cv.bitwise_and(roi, roi, mask=mask_inv)

# 获取得到前景图
img2_fg = cv.bitwise_and(img2,img2, mask=mask)

# 前景颜色和背景颜色合并
dst = cv.add(img1_bg,img2_fg)

# 复制粘贴
img1[start_rows:end_rows, start_cols:end_cols] = dst


# 可视化
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()

6,更改颜色空间

OpenCV中HSV颜色空间的取值范围为:H->[0,179], S->[0,255], V->[0,255]; 其它图像处理软件不一样

# 转换颜色空间
# 加载数据
img = cv.imread('opencv-logo.png')

# 转换为HSV格式
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)

# 图像可视化
cv.imshow('image', hsv)
cv.waitKey(0)
cv.destroyAllWindows()

7,形态学转换

腐蚀:去除边缘像素点。减少白色厚度,一般应用于只有黑白像素的灰度情况。cv.erode

扩张/膨胀:增加白色厚度。cv.dilate

open:先做一次腐蚀,再做一次扩张。去除噪音数据  cv.morphologyEx(op=cv.MORPH_OPEN) or  cv.erode->cv.dilate

close: 先扩张,在做腐蚀。去除前景中的黑色点 cv.morphologyEx(op=cv.MORPH_CLOSE) or  cv.dilate->cv.erode

top hat :原始图像跟open图像之间取差集

black hat:原始图像跟close图像之间取差集

8,图像梯度

通过对图像梯度的操作,可以发现图像的边缘信息

在OpenCV中提供了三种类型的高通滤波器,常见处理方式:Sobel、Scharr以及Laplacian导数

Canny算法是一种比Sobel和Laplacian效果更好的一种边缘检测算法。

            非极大值抑制:如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为 边缘点,否则该像素点被抑制

            双阈值检测:基于阈值来判断是否属于边;即如果像素边缘的梯度值高于 高阈值,则将其标记为强边缘像素,如果像素边缘的梯度值小于 高阈值并且大于低阈值,则将其标记为弱边缘像素,如果像素边 缘的梯度值小于低阈值,则会将其抑制

            抑制孤立弱边缘:通过查看弱边缘像素及其周边的八个邻域像素, 主要其中有一个为强边缘像素,则该弱边缘点被保留为真实边缘。 其算法原理是:真实的弱边缘像素一定是连接强边缘像素点的。

9,直方图

OpenCV中的直方图的主要功能是可以查看图像的像素信息

# 加载图像
img = cv.imread('koala.png', 0)

# 两种方式基本结果基本类似
# 基于OpenCV的API计算直方图
hist1 = cv.calcHist([img], channels=[0], mask=None, histSize=[256], ranges=[0,256])
# 基于NumPy计算直方图
hist2, bins = np.histogram(img.ravel(), 256, [0, 256])
# 和np.histogram一样的计算方式,但是效率快10倍
hist3 = np.bincount(img.ravel(), minlength=256)

# 可视化
plt.subplot(131)
plt.imshow(img, 'gray')
plt.title('Original Image')

plt.subplot(132)
plt.plot(hist3)
plt.title('Hist')

plt.subplot(133)
# 可以直接使用matpliab中的hist API直接画直方图
plt.hist(img.ravel(), 256, [0, 256])
plt.title('Hist2')

plt.show()

直方图均衡化:如果某一个图像的像素仅限制于某个特定的范围,但是实际上一个比较好的图像像素点应该是在某一个范围内,所以需要将像素的直方图做一个拉伸的操作;比如:一个偏暗的图像,像素基本上都在较小的位置,如果将像素值增大,不就可以让图像变亮嘛!实际上,直方图均衡化操作是一个提高图像对比度的方式

人脸识别

# 加载定义好的人脸以及眼睛信息匹配信息
face_cascade = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier('haarcascade_eye.xml')

# 加载图像
img = cv.imread('faces2.png')
# 转换为灰度图像
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 检测图像
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
    # 画人脸区域
    cv.rectangle(img, (x,y), (x+w, y+h), (255,0,0), 2)
    
    # 获得人脸区域
    roi_gray = gray[y:y+h, x:x+w]
    roi_img = img[y:y+h, x:x+w]
    
    # 检测眼睛
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex, ey, ew, eh) in eyes:
        # 画眼睛
        cv.rectangle(roi_img, (ex,ey), (ex+ew, ey+eh), (0,0,255), 2)

# 可视化
cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值