利用2024年1月20、21日 两天时间对 openCv + python 进行了学习
目前进度到 Mat 的 深拷贝与 浅拷贝
总结如下:
1.1 创建和显示窗口、加载图片/视频、保存图片/视频、从摄像头/视频中截取片段;
第一部分:简单的图片读取、显示、保存
import cv2
cv2.namedWindow('img',cv2.WINDOW_NORMAL)
img = cv2.imread('D:\\123.PNG') #imread('path,flag'):path文件路径,flag值为0则转换为黑白图,1为彩色
while True:
cv2.imshow('img',img)
key = cv2.waitKey(0)
if(key & 0xFF == ord('q')): #key & 0xFF == ord('q'):以此可判断 按q键
break
elif(key & 0xFF == ord('s')): #key & 0xFF == ord('s'):同上
cv2.imwrite('D:\\122233.png',img) #注意:如果路径写为:D:\12223.PNG则会填写到奇怪的位置,可能是此时\12有其他含义
#在python中\作为转义符使用,所以路径要用\\
cv2.destroyAllWindows()
第二部分:截取视频片段、保存截取片段(这段中对于cv2.VideoWriter_fourcc的内容有遗忘故重温)
简单的:利用cv2.VideCapture() :ret,frame = cv2.VideoCapture() 读取视频帧并展示
import cv2
cv2.namedWindow('video',cv2.WINDOW_NORMAL)
cv2.resizeWindow('video',640,400)
#获取设备视频/从视频文件中读取视频
cap = cv2.VideoCapture("D:\\fuck.MP4")
while True:
#读取视频帧
ret, frame = cap.read() #利用这个方法读取cap中的视频帧
cv2.imshow('video',frame) #展示读取到的视频帧
key = cv2.waitKey(1) #括号中的值越小,视频越流畅,如果为0则一直等待 键盘输入
if(key & 0xFF == ord('q')):
break
cap.release()
cv2.destroyAllWindows()
复杂的:截取视频片段
import cv2
fourcc = cv2.VideoWriter_fourcc(*'XVID') #定义fourcc;windows系统使用XVID
vw = cv2.VideoWriter('D:\\444.mp4',fourcc,1,(720,960)) #定义vw参数进行视频的保存:1表示被创建视频的帧率;(文件路径,定义的fourcc,帧率,分辨率):ps分辨率需要和原视频保持一致,可在播放器中查看分辨率
#创建窗口
cv2.namedWindow('video',cv2.WINDOW_NORMAL)
cv2.resizeWindow('video',640,360)
#获取设备视频/从视频文件中读取视频
cap = cv2.VideoCapture("D:\\fuck.MP4")
while True:
#读取视频帧
ret, frame = cap.read()
if ret == True:
cv2.imshow('video',frame)
cv2.resizeWindow('video',640,360)
#写数据到多媒体文件
vw.write(frame)
#q退出
key = cv2.waitKey(1)
if(key & 0xFF == ord('q')):
break
else:
break
vw.release()
cap.release()
cv2.destroyAllWindows()
1.2 鼠标控制和TrackBar(一种可调按钮)的使用
第一部分:鼠标控制(监测鼠标)
import cv2
import numpy as np
#鼠标回调函数
def mouse_callback(event,x,y,flags,userdata): #event 鼠标进行的操作如点击左键点击右键等;flags 进行的组合操作如按住鼠标左键和shift键(这项内容有待精进)
print(event,x,y,flags,userdata)
#mouser_callback(1,100,100,16,"666")
#创建窗口
cv2.namedWindow('mouse',cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse',640,400)
#设置鼠标回调
cv2.setMouseCallback('mouse',mouse_callback,'123')
#显示窗口和背景
img = np.zeros((400,640,3),np.uint8) #利用numpy绘制一个高400长640的纯黑窗口;此处尺寸和窗口宽高相反,3的意思是3层RGB就是三层;uint8指位深为8最大值则为255(色彩越丰富的图像位深越大)
while True:
cv2.imshow('mouse',img)
key = cv2.waitKey(1)
if key & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
第二部分:TrackBar
第1部分:调节图片色彩(RGB)
import cv2
import numpy as np
#定义callback函数
def callback():
pass
#创建窗口
cv2.namedWindow('trackbar',cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar',1200,800)
#创建trackbar
cv2.createTrackbar('R','trackbar',0,255,callback)
cv2.createTrackbar('G','trackbar',0,255,callback)
cv2.createTrackbar('B','trackbar',0,255,callback)
#创建纯黑背景图片
img = np.zeros((800,1200,3),np.uint8)
while True:
#获取当前trackbar的值
r = cv2.getTrackbarPos('R','trackbar')
g = cv2.getTrackbarPos('G','trackbar')
b = cv2.getTrackbarPos('B','trackbar')
#改变背景颜色
img[:] = [b,g,r]
cv2.imshow('trackbar',img)
key = cv2.waitKey(10)
if key & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
第二部分:将RBG色彩转换为其他类型如BGRA? GRAY? HSV等
遇到的问题:
1)第一次接触数据,被数组长度卡住:因为数组是从0开始计数
2)为了显示原色彩尝试了使用将原色彩(BGR)添加到色彩数组中失败,故选用增加BGRA这一色彩,BGRA与BGR显示效果相同,但是多了一个通道,也就是Alpha透明度值
相关文章在这里:https://blog.csdn.net/2301_77872917/article/details/135723220?spm=1001.2014.3001.5502
import cv2
def callback():
pass
#创建窗口'color'
cv2.namedWindow('color',cv2.WINDOW_NORMAL)
cv2.resizeWindow('color',400,260)
#读取图片
img = cv2.imread('D:\\12223.png')
#色彩转换的数组包括三种类型
colorspaces = [cv2.COLOR_BGR2BGRA,cv2.COLOR_BGR2RGB,cv2.COLOR_BGR2GRAY,cv2.COLOR_BGR2HSV]
cv2.createTrackbar('curcolor','color',0,len(colorspaces)-1,callback)
while True:
index = cv2.getTrackbarPos('curcolor','color')
#颜色空间转换API
cvt_img = cv2.cvtColor(img,colorspaces[index])
cv2.imshow('color',cvt_img)
key = cv2.waitKey(1)
if key % 0xFF == ord('q'):
break
cv2.destroyAllWindows()
2.1 openCv核心知识
--------------分割线,现在时间2024年1月21日22:38分,夜已深明日还需搬砖,故休息----------------
插播一下心路历程:想做一个利用图像处理技术的? 可以用来管理带有编号信息的物品的? 移动设备;所以进行了openCv学习;个人认为openCv学起来不难,只要兴趣足应该可以啃下来
计划:学习资料视频还有约11小时,二倍速进行学习,看完视频需5.5小时,每个视频需要付出看视频用时的2倍进行理解、操作,故需要共5.5 * 3 = 16.5小时,每晚可支配的且注意力集中的时间约为3小时,大约需要5天多的时间学习全部内容;加上平日有生活琐事需要处理以及其他不可抗的搬砖因素,故需要加上周末时间;
ps:可在单位 休息(摸鱼)时间 利用 单位资源(破电脑)机行碎片化的学习;
结论:
1)利用下周整周时间完成对openCv的学习 即可 视为 达标;
2)如果在周六前完成 即可 视为 优秀;?
because 周四 == 发工资
so
if chengji = ‘优秀’? ? ??
奖励自己 ‘一个电子产品(没啥想买的)’
睡了zzzzzZZZZZZ.........................
---------------分割线,以上是待更新内容区域--------------------------------
2024年01月23日插播一下
今日只刷了5.5小时中的0.255,还远没有达成今日目标量
但是遇到了一个大作业,即《添加logo》
这部分内容是
1)图像的 加 减 融合 运算
2)与 非 或 异或 操作
的综合使用
涉及到一个关键内容,即添加logo的逻辑,内容如下
首先需要制作 “掩码”,也就是指定要进行添加logo的区域
掩码的优势在于:选取原图中的一个“大范围”,在这个范围中添加logo,此时将logo
想要放置的区域值变为 0 ,这样添加的logo 就能直接体现色彩,不会受到运算的影响
而显示出不理想的颜色
制作掩码中遇到一个问题:(一段代码)
tmp = cv2.bitwise_and(roi,roi, mask = m)
tmp = cv2.bitwise_and(roi,m)
第一行为正确代码,第二行为错误代码
原因:roi是我们选区的原图中的区域,是一个三通道即RGB的区域;但是m是一个黑白两色的区域,因此不能直接进行and操作
在请教chatgpy时他为我做了很好的解答:
首先,他推荐我将roi区域的三个通道拆分,分别与m进行操作,这样就可以直接进行and操作,然后再将三个通道合并,代码如下
# 将 roi 拆分成通道
b, g, r = cv2.split(roi)
# 对每个通道与 m 进行按位与操作
b = cv2.bitwise_and(b, m)
g = cv2.bitwise_and(g, m)
r = cv2.bitwise_and(r, m)
# 将通道重新合并
tmp = cv2.merge([b, g, r])
这样就可以很直观的理解roi不能和m直接进行and操作的原因了
但是我们需要更好的理解更优质的代码,于是又与chatgpt进行了交流
dst = cv2.bitwise_and(src1, src2, mask=mask)
tmp = cv2.bitwise_and(roi, roi, mask=m)
chatgpy原文:这行代码的目的是将 roi
中所有非零掩码位置的像素值保留,其他位置的像素值设置为零,形成一个新的图像 tmp
。这个操作实际上就是将 roi
中的区域按照 m
的掩码进行裁剪,只保留掩码为非零的部分。其他部分归零
PS:
roi
是原始图像中选取的区域,这个区域的大小与 logo 的大小相同。
m
是掩码,其中掩码的非零部分表示对应位置要保留的像素。
以上述内容为原题,我完成了大作业的全部代码,并理解了logo绘制的正确逻辑
以下为本人独立完成的《“原创加logo”大作业》🆒
import cv2
import numpy as np
#绘制logo
img = cv2.imread('D:\\123.PNG') #读取需要加水印的图片
logo = np.zeros((200,200,3),np.uint8) #创建logo(其实是包括logo在内的一片区域)
logo[130:180,30:170] = (0,0,255) #真正的绘制了logo
logo[20:150,70:130] = (255,0,0) #真正的绘制了logo
mask = np.zeros((200,200),np.uint8) #为掩码制作区域,尺寸必然与logo区域一致,解释见原文
mask[130:180,30:170] = 255 #掩码中logo真正占的区域,必然与logo真正的尺寸一致,解视见原文
mask[20:150,70:130] =255 #掩码中logo真正占的区域,必然与logo真正的尺寸一致,解视见原文
m = cv2.bitwise_not(mask) #这一步之前的掩码区域是,黑色的背景值为0,logo在掩码中的区域为白色值为1
#这段代码是通过非操作,使得背景值都变为1,logo占的区域变为0,为后续做铺垫
roi = img[0:200,0:200] #读取原图中打水印的区域,尺寸必然与mask尺寸一致,因为bitwise_and要求图片尺寸一致
tmp = cv2.bitwise_and(roi,roi, mask = m) #tmp temporary临时变量 与操作也就是求交集
#此时m中logo在掩码中占的区域值都为0,与原图进行与操作也就是取交集自然得到空集,也就是0
#这步完成后,就得到了一个包含取出的原图区域且logo需要占有的区域值为0的结果,这样在将logo加入进去,就不会影响logo真实的色彩
#如果抛弃这些步骤,直接画好logo,通过add或者addweighted操作,都会使加入图片的logo色彩不是我们想要的颜色
dst = cv2.add(tmp,logo) #dst destination目标 将tmp与logo加起来,也就得到了加好logo的原图的一部分
img[0:200,0:200] = dst #直接赋值,将原图中x范围0~200;y范围:0~200;尺寸为200x200的区域 赋dst的值,也就是将dst这个图加进了原图中
cv2.imshow('logo' , logo)
cv2.imshow('musk' , mask)
cv2.imshow('m',m)
cv2.imshow('roi',roi)
cv2.imshow('tmp' , tmp)
cv2.imshow('img',img)
cv2.waitKey(0)
#有不懂的兄弟尽管问我,就当让我复习了,还有就是第21行这段代码不太好理解,在原文中都有解答,也可以评论提问!
下图为每个窗口的展示,便于理解
有不懂的朋友尽管评论提问,就当给俺复习了
---------分割线-----------------------------------