python+opencv学习笔记

(以下内容有点散乱,主要是个人笔记记录,希望部分内容对你有所帮助)

目录

1.学习背景

2.视频帧读取+保存jpg+MP4

3.opencv  cv.imshow()注意点

1.学习背景

本次学习是组长给我了几张没有任何头文件等信息的raw图(之前弄的都是jpg,png,raw的打开包括使用确实麻烦挺多),并将其打开显示,其中通过Photopea | Online Photo Editor这个网站先去浏览了一下图片的大概内容,只能看大概内容,因为这些软件等只是智能帮你适配合适的尺寸,但具体归一化等操作还是需要你自己去弄。最终得出的结果就是四张raw来自不同设备,两张只是单张raw图,一张是由两张图片拼装在一起,一张是由多张视频帧保存成一张图片。

(具体raw1,2,3操作打开可见上篇文章Python读取显示raw图片+numpy基本用法记录_道人兄的博客-CSDN博客)

2.视频帧读取+保存jpg+MP4

①视频帧的截取+jpg保存

在raw所读取的numpy数组中,单帧图片的顺序是与在数组中数据等同的,所以我们只需要获取单帧图片的尺寸,进而算出单帧图片size(这里需要手动去调,调的过程中会发现很多重复的内容,调到只剩下单帧的内容时就是对应尺寸了,见下图)

python+opencv学习笔记_第1张图片python+opencv学习笔记_第2张图片

 所以我单帧便是384*288,原图尺寸是1728*1792,所以此时只需要运用img(x:x+s)就可以将我们单帧图片截取出来,下面是代码演示

import numpy as np
import cv2

# image为array类型,多少维度都无所谓,直接操作全部元素
img = np.fromfile("D:/VScode/pyproject/PR/view/showRaw/4.raw", dtype=np.uint16)
print(img)  
print("数组元素总数:",img.size)      #打印数组尺寸,即数组元素总数  

def imgv(img):
    s = 0
    # 计算单帧图的数量
    t = int(img.size/110592)
    # 生成个空向量可用来放置单帧图数组
    a = np.random.randint(0,1,(t,110592))
    print(a)
    for i in range(t):
        # 单帧截取
        a[i]  =img[s:s+110592]

        # /“x-min/max-min”归一化//
        imagec = (a[i] - np.min(a[i])) / (np.max(a[i]) - np.min(a[i]))
        # ///
        
        imgDatac = imagec.reshape(288, 384, 1)
        s = s+ 110592
        print("显示第%d张图片"%(i+1))
        imgDatac = imgDatac*255
        cv2.imwrite("D:/VScode/pyproject/PR/view/rawview/p4jpg/4.{}.jpg".format(i+1),imgDatac)
    result = "每帧保存成功!"
    return result

result = imgv(img)
print(result)

python+opencv学习笔记_第3张图片

 ②视频帧保存mp4

视频读取只需要使用cv.vediowriter便可以将图保存为mp4格式,代码如下

import glob
import os
from ssl import PROTOCOL_TLSv1_2
import cv2

# //视频帧合成视频.mp4///
def pic2video(pic_root_path):

    fps = 10   # 设置视频帧率
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')  # 设置视频编码方式
    videoWriter = cv2.VideoWriter('result.mp4', fourcc, fps, (384,288))  # 创建videoWriter 实例,视频size需与图片size相同
    filePathNames = glob.glob(os.path.join(pic_root_path, '*.jpg'))  # 遍历目录下所有jpg文件
    filePathNames.sort()  # 排序
    n = len(filePathNames)
    for i in range(n):
        print('writing frame {}'.format(i))
        img = cv2.imread(filePathNames[i])
        videoWriter.write(img)
    videoWriter.release()
path = "D:/VScode/pyproject/PR/view/rawview/p4jpg/"
pic2video(path)

python+opencv学习笔记_第4张图片

3.opencv  cv.imshow()注意点

①在使用cv.imshow()过程中,当我图片array中出现了负数时,opencv会自动将负数抹除,然后用0进行代替,我试了一下自行将负数用0代替,然后图片跟没0处理的图去进行对比,发现是一模一样的,也验证了我的想法

import numpy as np
import cv2
import torch


# image为array类型,多少维度都无所谓,直接操作全部元素
img = np.fromfile("D:/VScode/pyproject/PR/view/showRaw/1.raw", dtype=np.uint16)

image = (img - np.average(img)) / np.std(img)
# 打印出来可以看出是有负数的
print(image)

imgData1 = image.reshape(288, 384, 1)
# 将负数置零 
imgData2= np.where(imgData1>0,imgData1,0)
print(imgData2)
imgData1 = imgData1*255
imgData2 = imgData2*255
cv2.imwrite("1.jpg",imgData1)
cv2.imwrite("2.jpg",imgData2)

python+opencv学习笔记_第5张图片

python+opencv学习笔记_第6张图片

 ②不同位数opencv显示处理不同

在做图像归一化之后,我按照之前所做的归一化之后将数据*255,然后将其显示,最后发现图片都曝光了,说我乘了之后数远大于255了,但是我print之后数明明没错,所以我怀疑问题应该是出在cv.imshow,我使用help(cv2.imshow)查看了官方说明文档,最终发现

python+opencv学习笔记_第7张图片

如果图像是8位无符号的,则显示为原样。

如果图像是16位无符号的,则像素被除以256。即将[0,255*256]的取值范围映射为[0,255]。

如果图像是32位或64位浮点,则像素值乘以255。即将取值范围[0,1]映射为[0,255]。

32位整数图像不再处理,由于需要的变换的模糊性。使用特定于图像上下文的自定义预处理转换为8位无符号矩阵

 而我的图像是16位的,在归一化之后数据变为64位,所以它自行给我数据*255,这也是为什么会曝光的原因,所以我的数据是不需要进行255灰度值化处理的

 以上便是本次学习笔记记录,我也是个新手,纯属个人想法哈哈哈,如果有什么表述或者理解错误,也麻烦各位大佬帮忙批评指正。

你可能感兴趣的:(学习,python,opencv,numpy,vscode)