openCv + python学习;阶段性回顾与总结 PS:基于 试验代码 进行回顾

发布时间:2024年01月23日

利用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行这段代码不太好理解,在原文中都有解答,也可以评论提问!

下图为每个窗口的展示,便于理解

有不懂的朋友尽管评论提问,就当给俺复习了

---------分割线-----------------------------------

文章来源:https://blog.csdn.net/2301_77872917/article/details/135736174
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。