(以下內容有點散亂,主要是個人筆記記錄,希望部分內容對你有所幫助)
目錄
1.學習背景
2.視頻幀讀取+保存jpg+MP4
3.opencv cv.imshow()注意點
本次學習是組長給我了幾張沒有任何頭文件等信息的raw圖(之前弄的都是jpg,png,raw的打開包括使用確實麻煩挺多),並將其打開顯示,其中通過Photopea | Online Photo Editor這個網站先去浏覽了一下圖片的大概內容,只能看大概內容,因為這些軟件等只是智能幫你適配合適的尺寸,但具體歸一化等操作還是需要你自己去弄。最終得出的結果就是四張raw來自不同設備,兩張只是單張raw圖,一張是由兩張圖片拼裝在一起,一張是由多張視頻幀保存成一張圖片。
(具體raw1,2,3操作打開可見上篇文章Python讀取顯示raw圖片+numpy基本用法記錄_道人兄的博客-CSDN博客)
①視頻幀的截取+jpg保存
在raw所讀取的numpy數組中,單幀圖片的順序是與在數組中數據等同的,所以我們只需要獲取單幀圖片的尺寸,進而算出單幀圖片size(這裡需要手動去調,調的過程中會發現很多重復的內容,調到只剩下單幀的內容時就是對應尺寸了,見下圖)
所以我單幀便是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)
②視頻幀保存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)
①在使用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)
②不同位數opencv顯示處理不同
在做圖像歸一化之後,我按照之前所做的歸一化之後將數據*255,然後將其顯示,最後發現圖片都曝光了,說我乘了之後數遠大於255了,但是我print之後數明明沒錯,所以我懷疑問題應該是出在cv.imshow,我使用help(cv2.imshow)查看了官方說明文檔,最終發現
如果圖像是8位無符號的,則顯示為原樣。
如果圖像是16位無符號的,則像素被除以256。即將[0,255*256]的取值范圍映射為[0,255]。
如果圖像是32位或64位浮點,則像素值乘以255。即將取值范圍[0,1]映射為[0,255]。
32位整數圖像不再處理,由於需要的變換的模糊性。使用特定於圖像上下文的自定義預處理轉換為8位無符號矩陣
而我的圖像是16位的,在歸一化之後數據變為64位,所以它自行給我數據*255,這也是為什麼會曝光的原因,所以我的數據是不需要進行255灰度值化處理的
以上便是本次學習筆記記錄,我也是個新手,純屬個人想法哈哈哈,如果有什麼表述或者理解錯誤,也麻煩各位大佬幫忙批評指正。