<html lang="zh-CN">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<body class="nodata " style="">
<main style="width:100%">
<div class="blog-content-box">
<div class="article-title-box">
<h1 class="title-article" id="articleContentId">opencv读取摄像头不是实时的处理方法</h1>
</div><div id="article_content" class="article_content clearfix">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-044f2cf1dc.css">
<div id="content_views" class="markdown_views prism-atom-one-dark">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<pre data-index="0" class="set-code-show prettyprint"><code class="prism language-python has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;">cap <span class="token operator">=</span> cv2<span class="token punctuation">.</span>VideoCapture<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
cap.read()
- 1
- 2
读取的不是实时的画面 ,存在延迟 怎么处理
如果你使用的是OpenCV库,你可以通过将缓冲区大小设置为更小的值来减小延迟。默认情况下,缓冲区大小是16,但可以通过在cv2.VideoCapture()中传递参数来更改。例如:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
- 1
- 2
- 3
这将把缓冲区大小减小到1,从而减小延迟。但是,如果你将缓冲区大小设置得太小,你可能会遇到画面卡顿或丢帧的问题。
另一种方式是使用多线程或异步处理来实现更快的画面更新。你可以在一个线程中读取摄像头的帧,并将它们传递到另一个线程或进程中进行处理和显示。这将使你能够更快地处理帧并减少延迟。但是,这需要更多的编程和计算资源,并可能会增加代码的复杂性。
下面是一个基本的多线程处理OpenCV视频帧的例子:
import cv2
import threading
class VideoCapture:
def __init__(self, src=0):
self.cap = cv2.VideoCapture(src)
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
self.grabbed, self.frame = self.cap.read()
self.started = False
self.read_lock = threading.Lock()
<span class="token keyword">def</span> <span class="token function">start</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token keyword">if</span> self<span class="token punctuation">.</span>started<span class="token punctuation">:</span>
<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'VideoCapture already started'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token boolean">None</span>
self<span class="token punctuation">.</span>started <span class="token operator">=</span> <span class="token boolean">True</span>
self<span class="token punctuation">.</span>thread <span class="token operator">=</span> threading<span class="token punctuation">.</span>Thread<span class="token punctuation">(</span>target<span class="token operator">=</span>self<span class="token punctuation">.</span>update<span class="token punctuation">,</span> args<span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
self<span class="token punctuation">.</span>thread<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> self
<span class="token keyword">def</span> <span class="token function">update</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token keyword">while</span> self<span class="token punctuation">.</span>started<span class="token punctuation">:</span>
grabbed<span class="token punctuation">,</span> frame <span class="token operator">=</span> self<span class="token punctuation">.</span>cap<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">with</span> self<span class="token punctuation">.</span>read_lock<span class="token punctuation">:</span>
self<span class="token punctuation">.</span>grabbed <span class="token operator">=</span> grabbed
self<span class="token punctuation">.</span>frame <span class="token operator">=</span> frame
<span class="token keyword">def</span> <span class="token function">read</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token keyword">with</span> self<span class="token punctuation">.</span>read_lock<span class="token punctuation">:</span>
grabbed <span class="token operator">=</span> self<span class="token punctuation">.</span>grabbed
frame <span class="token operator">=</span> self<span class="token punctuation">.</span>frame
<span class="token keyword">return</span> grabbed<span class="token punctuation">,</span> frame
<span class="token keyword">def</span> <span class="token function">stop</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
self<span class="token punctuation">.</span>started <span class="token operator">=</span> <span class="token boolean">False</span>
self<span class="token punctuation">.</span>thread<span class="token punctuation">.</span>join<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">__exit__</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> exc_type<span class="token punctuation">,</span> exc_value<span class="token punctuation">,</span> traceback<span class="token punctuation">)</span><span class="token punctuation">:</span>
self<span class="token punctuation">.</span>cap<span class="token punctuation">.</span>release<span class="token punctuation">(</span><span class="token punctuation">)</span>
if name == ‘main‘:
cap = VideoCapture(0).start()
while True:
grabbed, frame = cap.read()
if not grabbed:
break
cv2.imshow(‘frame’, frame)
if cv2.waitKey(1) & 0xFF == ord(‘q’):
break
cap.stop()
cv2.destroyAllWindows()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
这个例子使用了一个VideoCapture类,该类在一个线程中不断读取摄像头帧,并将它们保存在一个共享的grabbed和frame变量中。在主程序中,我们通过调用start()方法来启动线程,然后不断读取帧并在窗口中显示它们,直到用户按下’q’键退出。最后,我们调用stop()方法来停止线程并释放资源。
需要注意的是,这个例子仅仅是一个基本的框架,你可能需要对其进行修改和扩展以适应你的具体应用场景。例如,你可以添加一个另一个线程来处理帧,然后显示处理后的结果,以此来减少延迟。