CV计算机视觉核心01-计算机视觉基础(基本图像处理OpenCV)

CV计算机视觉核心01(直接用生成矩阵的方式生成图片、查看矩阵数值以及大小、matplotlib使用例子、彩色图像的颜色空间转换、从摄像头或视频采集图像、frame 的大小是多少?、从文件读取图像数据、range of interest ROI、 黑白图像、彩色图像、rgb2hsv、颜色空间转换、肤色检测、二值化、放射矩阵M、图像的放大与缩小、移动、图像的旋转变换、拉伸变换、斜切、图像模糊与锐化、GaussianBlur高斯模糊、Canny Sobel滤波 边缘检测、图像滤波/卷积 锐化、 加水印,保护版权实例)

JupyterLab

a=[1,2,3]
print("Hello friends,welcome week1's class  .........",29*"-","%s"%(a))

在这里插入图片描述

import cv2
import numpy as np

直接用生成矩阵的方式生成图片

img0 = np.array([[0,0,1],[0,1,0],[1,0,0]])
#img0 = np.array([[0,0,1],[0,1,0],[1,0,0]])

查看矩阵数值以及大小

print(img0)

在这里插入图片描述

print(img0.shape)
print("img0 size = %s,%s"%(img0.shape[0],img0.shape[1]))

在这里插入图片描述

import matplotlib.pyplot as plt
# import matplotlib.pylab as plt
plt.imshow(img0,cmap = 'gray' )
# color map 
#plt.imshow(img0)

# pycharm要加一句:plt.show() 
# 加一个%matplotlib inline就会显示

在这里插入图片描述

matplotlib使用例子

# https://www.cnblogs.com/yanghailin/p/11611333.html

彩色图像的颜色空间转换

# https://blog.csdn.net/zhang_cherry/article/details/88951259

从摄像头或视频采集图像

# read camera
#cap = cv2.VideoCapture(0)
# read video
#cap  = cv2.VideoCapture("/Users/zhaomingming/Documents/HTC/核心课/CVFundamentals/week1/How Computer Vision Works.mp4")
#cap = cv2.VideoCapture("../How Computer Vision Works.mp4")
path = r"D:\whole_development_of_the_stack_study\RS_Algorithm_Course\为其1年的CV课程\06计算机视觉-视觉任务基础理论\CCV4-master\How Computer Vision Works.mp4"
cap = cv2.VideoCapture(path)
print(cap.isOpened())

在这里插入图片描述

return_value=True
if return_value:
    # frame 图像帧
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    return_value,frame = cap.read()
    print(cap.isOpened())

    #发现图片发蓝
    #plt.imshow(frame,cmap = 'gray')
    
    #解决方法:cv2.cvtColor()
    #cv2.COLOR_BGR2RGB 调换一下显示的通道
    #这里是真彩色显示:
    plt.imshow(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))

在这里插入图片描述

frame 的大小是多少?

print(frame.shape)#这个视频大小是360*640,3个通道

在这里插入图片描述

#注意这里要关闭capture,否则会一致保存这个在内存中
cap.release()

从文件读取图像数据

#读取图片
img  = cv2.imread("lena.jpg")

#cv2.cvtColor()
#cv2.COLOR_BGR2RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
print(img.shape)

在这里插入图片描述

range of interest ROI

roi = img[100:200,300:400]
plt.imshow(img)

在这里插入图片描述

plt.imshow(roi)

在这里插入图片描述

黑白图像

img_gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#其内部是将三个通道合成一个通道的过程,即三个矩阵合成一个矩阵。
#三个矩阵对应位置进行加权计算(R*权重+G*权重+B*权重),从而获得一个矩阵。
#也可以直接使用某一个矩阵,其他两个直接舍弃

img_gray.shape

在这里插入图片描述

plt.imshow(img_gray,cmap='gray')

在这里插入图片描述

彩色图像

rgb2hsv

rgb用于机器显示
hsv便于人眼辨别
H色调 S饱和度 V明度

颜色空间转换

import cv2
img_BGR = cv2.imread('lena.jpg')
img_hsv=cv2.cvtColor(img_BGR,cv2.COLOR_BGR2HSV)
plt.imshow(img_hsv,cmap='hsv')
img_hsv.shape

在这里插入图片描述

肤色检测 根据肤色颜色范围来选取

# 肤色检测 根据肤色颜色范围来选取
import cv2
import matplotlib.pyplot as plt

def t2s(img):
    return cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

img = cv2.imread("week1_homework.png")
plt.figure(figsize=(2,2))
plt.imshow(t2s(img))
plt.show()

在这里插入图片描述

#滤波操作
import numpy as np
kernel = np.ones((3,3),np.float32)
kernel = kernel/9.
kernel=-kernel

# y轴方向上的梯度
# kernel[0,:]=[-1,-1,-1]
# kernel[1,:]=[0,0,0]
# kernel[2,:]=[1,1,1]

# 平均滤波,模糊的效果
# kernel[0,:]=[0.1,0.1,0.1]
# kernel[1,:]=[0.1,0.2,0.1]
# kernel[2,:]=[0.1,0.1,0.1]

# x轴方向上的梯度
kernel[0,:]=[-1,0,1]
kernel[1,:]=[-1,0,1]
kernel[2,:]=[-1,0,1]
#dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]);当ddepth=-1时,表示输出图像与原图像有相同的深度。
print(img.shape)
#滤波操作
result = cv2.filter2D(img,-1,kernel)
result.shape
print(result[0,0]) #打印出了0,0这个位置的三个通道对应的像素值。
plt.figure(figsize=(20,20))
plt.imshow(t2s(cv2.hconcat([img,result])))
plt.show()

在这里插入图片描述

去除脸上的斑点

看不出明显效果,更大滤波核,更多次滤波

#均值滤波
kernel_size=21
kernel = np.ones((kernel_size,kernel_size),np.float32)/(kernel_size*kernel_size)
#kernel[i][j]

#filter2D是一个卷积运算
img1 = cv2.filter2D(img,-1,kernel)
rmg1 = cv2.filter2D(img1,-1,kernel)
#rmg1 = cv2.filter2D(img1,-1,kernel)
#rmg1 = cv2.filter2D(img1,-1,kernel)
#rmg1 = cv2.filter2D(img1,-1,kernel)
result = cv2.filter2D(img1,-1,kernel)

显示滤波前后对比图

plt.figure(figsize=(20,20))
plt.imshow(t2s(cv2.hconcat([img,result])))
plt.show()

在这里插入图片描述

只对肤色区域进行滤波

进行肤色检测

result_show=result.copy()

# 肤色检测
# 来源 https://www.cnblogs.com/demodashi/p/9437559.html
# 把图像转换到HSV色域
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 

# 图像分割, 分别获取h, s, v 通道分量图像
(_h, _s, _v) = cv2.split(hsv) 

# 根据源图像的大小创建一个全0的矩阵,用于保存图像数据
#skin3 = np.zeros(_h.shape, dtype=np.uint8)  

# 根据源图像的大小创建一个全0的矩阵,用于保存图像数据
skin3 = np.zeros(_h.shape, dtype=np.float32) 

# 获取源图像数据的长和宽
(height,width) = _h.shape 

# 遍历图像, 判断HSV通道的数值, 如果在指定范围中, 则置把新图像的点设为255,否则设为0
for i in  range(0, height):
    for j in  range(0, width):
        #满足判断要求的像元就是肤色区域
        #这个判断肤色的是靠经验的
        if (_h[i][j] >  5) and (_h[i][j] <  120) and (_s[i][j] >  18) and (_s[i][j] <  255) and (_v[i][j] >  50) and (_v[i][j] <  255):
            #给对应位置的空矩阵赋值为1,说明该位置为皮肤
            skin3[i][j] =  1.0
            # dtype:uint8
            #result[i][j]=img[i][j]
        else:
            skin3[i][j] =  0.0 #黑色
            
            #这里比较重要:
            #img[i][j]是原图上的位置
            #result_show[i][j]是滤波后的copy,所有的像元都进行滤波了。
            #如果这个像元,不是皮肤,那么就用原图该像元代替滤波后的像元。
            result_show[i][j]=img[i][j]
            #皮肤依然是滤波操作后的像元,而眼睛,眉毛等就是原图的了。
            
#cv2.imshow(imname, img)
#cv2.imshow(imname +  " Skin3 HSV", skin3)
#cv2.imwrite("skin.png",skin3)
#import os
#os.system("open skin.png")
#cv2.imwrite("compare2.png",cv2.hconcat([img,result_show]))
#os.system("open compare2.png")
plt.figure(figsize=(20,20))
plt.imshow(t2s(cv2.hconcat([img,result_show,result])))
plt.show()

在这里插入图片描述

#显示一下判别肤色的结果
plt.figure(figsize=(10,10))
plt.imshow(t2s(skin3))
plt.show()

在这里插入图片描述

如何准确的得到人脸五官区域?

在这里插入图片描述

依赖人脸关键点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

依赖深度学习语义分割模型

在这里插入图片描述

二值化

import cv2
img =  cv2.imread('lena.jpg')
_,img_bw=cv2.threshold(img,128,255,cv2.THRESH_BINARY)
# 阈值为128,小于128为0,大于128为255,类型为二进制
print(_)
print(type(img_bw))
print(img_bw.shape)

在这里插入图片描述

plt.imshow(img_bw[:,:,0],cmap='gray')

在这里插入图片描述

放射矩阵M:

图像的放大与缩小

近邻法填充,是按照某一规则填充(容易产生mosic)
在这里插入图片描述

双线性插值
在这里插入图片描述
resize是需要插值的,默认应该是近邻法的插值

# 列,行
# 调整一下颜色
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
# 调整图片大小 这里是50,30
img =cv2.resize(img,(50,30))

plt.imshow(img)
img.shape

在这里插入图片描述

# 列,行
img =  cv2.imread('lena.jpg')
print(img.shape) #原图大小
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 调整图片大小 这里是500,300
img =cv2.resize(img,(500,500))
plt.imshow(img)
img.shape
#可以发现resize为50,30的时候图片失真严重。

在这里插入图片描述

# roi
img_roi =img[100:300,0:200]
plt.imshow(img_roi)

在这里插入图片描述

import numpy as np

#缩放矩阵
# 2表示x轴放大2倍,10表示y轴放大10倍
M = np.float32([[2,0,0],[0,4,0]])
print(M) 

print(img[0+50,0])

# 这里的(1000,1000)表示的是底图的大小
# Affine是仿射的意思,是针对刚体的变换
img_1=cv2.warpAffine(img,M,(2000,2000))

plt.imshow(img_1)
print(img_1[200+50,300])

在这里插入图片描述

移动:

在这里插入图片描述

import numpy as np

#移动矩阵
# tx=100,ty=-50,这里的负数表示向上移动。
M = np.float32([[1,0,100],[0,1,-50]])
print(M) 

print(img[0+50,0])

# 这里的(1000,1000)表示的是底图的大小
img_1=cv2.warpAffine(img,M,(800,500))

plt.imshow(img_1)
print(img_1[200+50,300])

在这里插入图片描述

图像的旋转变换

#pts1 = np.float32([[50,50],[200,50],[50,200]])
#pts2 = np.float32([[10,100],[200,50],[100,250]])
#M = cv2.getAffineTransform(pts1,pts2)
#print(M)
#180/3.14
# 旋转矩阵
# 角度的正负表示旋转的正逆
#M[[cos(),-sin(),tx],[sin(),cos(),ty]]
theta=0.5
M = np.float32([[np.cos(theta),-np.sin(theta),0],[np.sin(theta),np.cos(theta),0]])
# M = np.float32([[0.1,0,100],[0,2,100]])
# 变换矩阵,平移,斜切,旋转
# affine
cols=800
rows=800
dst = cv2.warpAffine(img,M,(cols,rows))
plt.imshow(dst)

在这里插入图片描述

拉伸变换

在这里插入图片描述

#拉伸不属于刚体变换

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[20,0],[0,300],[300,300]])
# 这里.getPerspectiveTransform()操作就是将pts1的4个点,拉伸到pts2的4个点。
# 获得该拉伸变换的M矩阵
M = cv2.getPerspectiveTransform(pts1,pts2)
print(M) #发现M是3*3的矩阵,这个相对来说复杂一些。但也都是矩阵变换。

# 拉伸变换后者透视变换
dst = cv2.warpPerspective(img,M,(300,300))
plt.imshow(dst)

在这里插入图片描述

斜切

#pts1 = np.float32([[50,50],[200,50],[50,200]])
#pts2 = np.float32([[10,100],[200,50],[100,250]])
#M = cv2.getAffineTransform(pts1,pts2)
#print(M)
#180/3.14
# 旋转矩阵
# 角度的正负表示旋转的正逆
#M[[cos(),-sin(),tx],[sin(),cos(),ty]]
theta=0.5
M = np.float32([[0.5,0.2,0],[0.3,1,0]])
# 变换矩阵,平移,斜切,旋转
# affine
cols=800
rows=800
dst = cv2.warpAffine(img,M,(cols,rows))
plt.imshow(dst)

在这里插入图片描述

图像模糊与锐化

下图中的kernal是一个均值滤波,因为是0.25,且kernal是2*2的,因此相当于每个像元乘以1/4。
在这里插入图片描述

GaussianBlur高斯模糊

#滤波操作
#(5, 5)表示高斯矩阵的长与宽都是5,x的标准差取5,y的标准差取5。
img= cv2.GaussianBlur(img, (5, 5), 5, 5)  # 高斯模糊
plt.imshow(img)

在这里插入图片描述

Canny Sobel滤波 边缘检测

# 第一个参数是需要处理的原图像,该图像必须为单通道的灰度图;
# 第二个参数是阈值1。
# 第三个参数是阈值2。
# 其中较大的阈值2用于检测图像中明显的边缘,但一般情况下检测的效果不会那么完美
img_b= cv2.Canny(img,30,100)
plt.imshow(img_b)

在这里插入图片描述

图像滤波/卷积 锐化

kernel = np.ones((3,3),np.float32)/8
kernel=-kernel
kernel[0,:]=[-1,-1,-1]
kernel[1,:]=[0,0,0]
kernel[2,:]=[1,1,1]


print(kernel)

在这里插入图片描述
这个kernel和求梯度是有关系的。梯度核。
这里的梯度核是[[-1,-1],[1,1]],这个核就是从下往上的梯度,也就是高浓度流向低浓度,即从1到-1方向,y轴梯度。
如果梯度核是[[1,-1],[1,-1]],这个核就是从左往右的梯度,也就是x轴梯度。

如下图的核是22的,那就是∂y1/∂x1 + ∂y2/∂x2 = (-10) + (-110) / (110) + (0*10) =0
在这里插入图片描述

plt.imshow(img) #原图像显示

在这里插入图片描述

print(img.shape)

#dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]);当ddepth=-1时,表示输出图像与原图像有相同的深度。
#ddepth:它是目标图像的理想深度。值 -1 表示生成的图像将具有与源图像相同的深度。
result = cv2.filter2D(img,-1,kernel)
print(result.shape)

#这里打印的是(100,0)这个位置上对应三个通道的值
print(result[100,0])

# 显示一下
plt.imshow(result*20)

在这里插入图片描述

result = cv2.filter2D(result,-1,kernel)

plt.imshow(result)
result.shape

在这里插入图片描述

# 形态学运算

# 灰度直方图

# 直方图均衡化

import torch
import matplotlib
!pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

在这里插入图片描述

from image_process import *
image_data = generate_data()

matplotlib 使用例子

https://www.cnblogs.com/yanghailin/p/11611333.html

import matplotlib.pyplot as plt
i=0
print(image_data[i%10])
plt.imshow(image_data[i%10],cmap = 'gray')
i=i+1

在这里插入图片描述

plt.imshow(cv2.imread('lena.jpg'))

在这里插入图片描述

img  = cv2.imread("lena.jpg")
img= cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

加水印,保护版权实例

add watermask

水印图片是:water2.png

wm = cv2.imread("water1.png")
plt.imshow(wm)

在这里插入图片描述

# 1、读取到图片
wm = cv2.imread("water2.png")
# 2、缩放调整大小
wm = cv2.resize(wm,(300,300))
# 3、255-wm,去除白色背景,此为字体不是纯黑0因此255-非0值,会得到一个其他的灰度。
wm = 255-wm
# 4、调整img大小,需要加水印图片的大小进行调整。
img1 = cv2.resize(img,(300,300))
#img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
print(wm.shape)

# 5、通过cv的add函数将两个图片添加到一起了。
plt.imshow(cv2.add(wm,img1))

在这里插入图片描述

#6、可以通过加权的方式,将两个图片叠加,两个图片权值可调。
#addWeighted参数中最后的那个0,表示亮度
plt.imshow(cv2.addWeighted(wm,0.9,img1,0.5,200))

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Henrik698

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值