python使用opencv提取視頻中的每一幀、最后一幀,并存儲成圖片

提取視頻每一幀存儲圖片

最近在搞視頻檢測問題,在用到將視頻分幀保存為圖片時,圖片可以保存,但是會出現(-215:Assertion failed) !_img.empty() in function 'cv::imwrite'問題而不能正常運行,在檢查代碼、檢查路徑等措施均無果后,了解了視頻分幀的原理后,才解決了問題,原因是缺少分幀結束的判斷條件,在寫入前,加上:

if frame is None;break
else:

在這里插入圖片描述

import cv2# 讀取視頻并分幀為圖片
video = cv2.VideoCapture("python/video/video2.mp4")
save_path = "python/img2"
index = 0
if video.isOpened():f = int(video.get(cv2.CAP_PROP_FPS))  # 讀取視頻幀率print("The video's fps is ", f)  # 顯示視頻幀率rval, frame = video.read()  # 讀取視頻幀
else:rval = False
while rval:print(index)rval,frame = video.read()cv2.imwrite(save_path + "/"+ str(index)+".jpg",frame)index += 1  

出現報錯的原因很簡單,在使用rval,frame讀取視頻的幀時,幀圖片保存在frame對應的索引里。而在寫入圖片時,沒有加入判斷條件,當視頻被分幀結束后,cv2.imread函數還在將空白信息寫入文件夾,所以會出現報錯,因此,只要在 cv2.imwrite(save_path + "/"+ str(index)+".jpg",frame)代碼前一行加入判斷條件,判斷分幀結束后,停止寫入即可。加入判斷條件:

if frame is None:break
else:

就可以正確導入分幀后的圖片了

正確的完整代碼如下:

import cv2# 讀取視頻并分幀為圖片video = cv2.VideoCapture("python/video/video2.mp4")
save_path = "python/img2"
index = 0
if video.isOpened():f = int(video.get(cv2.CAP_PROP_FPS))  # 讀取視頻幀率print("The video's fps is ", f)  # 顯示視頻幀率rval, frame = video.read()  # 讀取視頻幀
else:rval = Falsewhile rval:print(index)rval,frame = video.read()if frame is None:breakelse:cv2.imwrite(save_path + "/"+ str(index)+".jpg",frame)index += 1

正確輸出分幀后的圖片,并保存在文件夾中:

在這里插入圖片描述

提取視頻最后一幀存儲圖片

完整代碼:

import cv2# 打開視頻文件
cap = cv2.VideoCapture('python/video/video2.mp4')# 讀取視頻文件中的所有幀
frames = []
while cap.isOpened():ret, frame = cap.read()if not ret:breakframes.append(frame)# 檢查是否有幀可用
if len(frames) > 0:# 提取最后一幀并將其保存為圖像last_frame = frames[-1]cv2.imwrite('python/img/last.jpg', last_frame)print("last picture over")
else:print("錯誤:無法提取任何幀")# 釋放視頻文件句柄
cap.release()

在這個代碼中,我們首先讀取視頻文件中的所有幀,并將它們存儲在一個列表中。然后,我們檢查列表中是否有任何幀可用。如果有,則提取最后一幀并將其保存為圖像。否則,我們打印錯誤消息。

這里要注意,在這個代碼中,我們沒有使用while循環來遍歷所有幀,而是將所有幀讀取到一個列表中。這樣可以確保我們正確地獲取了最后一幀,而不會錯過任何幀。

如果仍然無法提取最后一幀,請確保視頻文件存在并且可讀,并嘗試使用其他視頻文件進行測試。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384985.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384985.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384985.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

結構體參數

結構體作為函數參數&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h>struct student {char name[10];int age; };void print_student(struct student s) {printf("name %s,age %d\n",s.name,s.age); } void set_studen…

線程間通信之eventfd

線程間通信之eventfd man手冊中的解釋&#xff1a; eventfd()創建了一個“eventfd對象”&#xff0c; 通過它能夠實現用戶態程序間(我覺得這里主要指線程而非進程)的等待/通知機制&#xff0c;以及內核態向用戶態通知的機制&#xff08;未考證&#xff09;。 此對象包含了一個…

【linux 開發】定時器使用setitimer

setitimer Linux 為每一個進程提供了 3 個 setitimer 間隔計時器&#xff1a; ITIMER_REAL&#xff1a;減少實際時間&#xff0c;到期的時候發出 SIGALRM 信號。ITIMER_VIRTUAL&#xff1a;減少有效時間 (進程執行的時間)&#xff0c;產生 SIGVTALRM 信號。ITIMER_PROF&#…

文件操作(寫)

/*** file.c ***/ #include<stdio.h>int main() {//用寫的方式打開一個文件 //w的意思是文件如果不存在&#xff0c;就建立一個文件&#xff0c;如果文件存在就覆蓋FILE *p fopen("/home/exbot/wangqinghe/C/20190716/file1.txt","w");fputs(&qu…

定時器timerfd

1.為什么要加入此定時器接口 linux2.6.25版本新增了timerfd這個供用戶程序使用的定時接口&#xff0c;這個接口基于文件描述符&#xff0c;當超時事件發生時&#xff0c;該文件描述符就變為可讀。我首次接觸這個新特性是在muduo網絡庫的定時器里看到的&#xff0c;那么新增一個…

文件操作(讀)

讀一行&#xff1a; #include<stdio.h> #include<string.h> #include<stdlib.h> const int maxn 10; int main() {char s[1024] {0};FILE *p fopen("/home/exbot/wangqinghe/C/20190716/file.txt","r");//第一個參數是一個內存地址&…

timerfd與epoll

linux timerfd系列函數總結 網上關于timerfd的文章很多&#xff0c;在這兒歸納總結一下方便以后使用&#xff0c;順便貼出一個timerfd配合epoll使用的簡單例子 一、timerfd系列函數 timerfd是Linux為用戶程序提供的一個定時器接口。這個接口基于文件描述符&#xff0c;通過文…

文件操作(解密加密)

文件加密&#xff1a; #include<stdio.h> #include<string.h> #include<stdlib.h>void code(char *s) {while(*s){(*s);s;} }int main() {char s[1024] {0};FILE *p fopen("/home/exbot/wangqinghe/C/20190716/file.txt","r");FILE *p…

linux僵尸進程產生的原因以及如何避免產生僵尸進程defunct

給進程設置僵尸狀態的目的是維護子進程的信息&#xff0c;以便父進程在以后某個時間獲取。這些信息包括子進程的進程ID、終止狀態以及資源利用信息(CPU時間&#xff0c;內存使用量等等)。如果一個進程終止&#xff0c;而該進程有子進程處于僵尸狀態&#xff0c;那么它的所有僵尸…

linux下僵尸進程(Defunct進程)的產生與避免

在測試基于 DirectFBGstreamer 的視頻聯播系統的一個 Demo 的時候&#xff0c;其中大量使用 system 調用的語句&#xff0c;例如在 menu 代碼中的 system("./play") &#xff0c;而且多次執行&#xff0c;這種情況下&#xff0c;在 ps -ef 列表中出現了大量的 defunc…

文件操作函數

fopen()函數參數&#xff1a; r 只讀的方式打開文件。 打開成功返回文件指針&#xff0c; 打開失敗返回NULL r 以讀寫方式打開文件。 文件必須存在 rb 以二進制模式讀寫文件&#xff0c;文件必須存在 rw 讀寫一個二進制文件&#xff0c;允許讀和寫 w 打開只寫文件&…

讀過的最好的epoll講解

首先我們來定義流的概念&#xff0c;一個流可以是文件&#xff0c;socket&#xff0c;pipe等等可以進行I/O操作的內核對象。 不管是文件&#xff0c;還是套接字&#xff0c;還是管道&#xff0c;我們都可以把他們看作流。 之后我們來討論I/O的操作&#xff0c;通過read&#xf…

文件操作函數(讀寫)

文件文本排序&#xff1a; 數組冒泡&#xff1a; #include<stdio.h>void swap(int *a,int *b) {int temp *a;*a *b;*b temp; }void bubble(int *p,int n) {int i;int j;for(i 0; i < n; i){for(j 1; j < n - i; j){if(p[j - 1] > p[j]){swap(&p[j-1],&…

文件操作(升級)

計算字符串“25 32 ” #include<stdio.h> #include<string.h>int calc_string(char *s) {char buf1[100] {0};char oper 0;char buf2[100] {0};int len strlen(s);int i;for(i 0; i < len; i){if( s[i] || - s[i] || * s[i] || / s[i] ){strncpy…

C語言指針轉換為intptr_t類型

C語言指針轉換為intptr_t類型 1、前言 今天在看代碼時&#xff0c;發現將之一個指針賦值給一個intptr_t類型的變量。由于之前沒有見過intptr_t這樣數據類型&#xff0c;憑感覺認為intptr_t是int類型的指針。感覺很奇怪&#xff0c;為何要將一個指針這樣做呢&#xff1f;如是果…

nginx epoll詳解

nginx epoll 事件模型 nginx做為一個異步高效的事件驅動型web服務器&#xff0c;在linux平臺中當系統支持epoll時nginx默認采用epoll來高效的處理事件。nginx中使用ngx_event_t結構來表示一個事件&#xff0c;先介紹下ngx_event_t結構體中成員的含義&#xff1a; struct ngx_ev…

Inotify機制

描述 Inotify API用于檢測文件系統變化的機制。Inotify可用于檢測單個文件&#xff0c;也可以檢測整個目錄。當檢測的對象是一個目錄的時候&#xff0c;目錄本身和目錄里的內容都會成為檢測的對象。 此種機制的出現的目的是當內核空間發生某種事件之后&#xff0c;可以立即通…

文件操作(二進制文件加密解密)

加密 #include<stdio.h> #include<string.h>void code(char *p,size_t n) {size_t i;for(i 0; i < n; i){p[i] 3;} }int main() {FILE *p1 fopen("./a.txt","r");FILE *p2 fopen("./b.txt","w");char buf[1024] {…

北京加密機現場select問題

問題描述 北京項目通過調用我們提供的庫libsigxt.a與加密機通信&#xff0c;c/s架構&#xff0c;客戶端啟用多個線程&#xff0c;每個線程流程有以下三步&#xff0c;連接加密機&#xff0c;簽名&#xff0c;關閉鏈接。在正常運行一段時間后會出現不能連接加密機服務問題。 連…

拼接字符串(帶參程序)

1.用strcat拼接函數可以實現 #include<stdio.h> #include<string.h>int main(int argc,char ** argv) {char str[100] {0};int i;for( i 1; i < argc; i){strcat(str,argv[i]);}printf("str %s\n",str);return 0; } 2.用sprintf函數也可以實現 #in…