2014-07-18 130 views
1

我已經成功地使用mjpeg-streamer從我的設備捕獲mjpeg流。下面的代碼是我如何檢索此流中的OpenCV的Python:從傳入的MJPEG流跟蹤OpenCV中的對象流

import cv2 
import numpy as np 
import urllib 

stream=urllib.urlopen('http://@192.168.7.2:8090/?action=stream/frame.mjpg') 
bytes='' 
while True: 
    bytes+=stream.read(1024) 
    a = bytes.find('\xff\xd8') 
    b = bytes.find('\xff\xd9') 
    if a!=-1 and b!=-1: 
     jpg = bytes[a:b+2] 
     bytes= bytes[b+2:] 
     i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.CV_LOAD_IMAGE_COLOR) 
     cv2.imshow('i',i) 
     if cv2.waitKey(1) ==27: 
      exit(0) 

我也有軌道基於其顏色範圍內的移動對象的代碼。這段代碼的視頻源直接從網絡攝像頭直接從OpenCV中取出。這是代碼:

import cv2.cv as cv 
import time 
import sys 

capture = CaptureFROMCAM(0) 

while True: 
img = cv.QueryFrame(capture) 


cv.Smooth(img,img,cv.CV_BLUR,3) 
hue_img = cv.CreateImage(cv.GetSize(img),8, 3) 
cv.CvtColor(img,hue_img, cv.CV_BGR2HSV) 

# Remove all the pixels that don't match 
threshold_img = cv.CreateImage(cv.GetSize(hue_img), 8, 1) 
cv.InRangeS(hue_img, (100,180,80), (225,160,80), threshold_img) 

# Find all the areas of color out there 
storage = cv.CreateMemStorage(0) 
contour = cv.FindContours(threshold_img, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) 

# Step through all the areas 
points = [] 
while contour: 
    # Get the info about this area 
    rect = cv.BoundingRect(list(contour)) 
    contour = contour.h_next() 
    # Check to make sure the area is big enough to be of concern 
    size = (rect[2] * rect[3]) 
    if size > 25: 
     pt1 = (rect[0], rect[1]) 
     pt2 = (rect[0] + rect[2], rect[1]+rect[3]) 
     # Add a rectangle to the initial image 
     cv.Rectangle(img, pt1, pt2, (15,15,255))  

threshold_img = cv.CreateImage(cv.GetSize(hue_img),8,1) 
cv.InRangeS(hue_img, (16,82,19), (30,255,255), threshold_img) 

cv.ShowImage("Color Tracking", img) 
cv.ShowImage("threshold", threshold_img)  

if cv.WaitKey(10) == 27: 
    success, frame = videoCapture.read() 
    while success: 
     videoWriter.write(frame) 
     success, frame = videoCapture.read() 
    break 

我的問題是:我怎樣才能將二者結合起來的過程,這樣我可以在第二個代碼中使用第一程序來完成作爲輸入的圖像處理解碼JPEG圖像?我嘗試了各種各樣的組合,但我仍然沒有任何運氣。我不斷收到錯誤

cv.QueryFrame有沒有有效的論據「捕捉」

這告訴我,它不順心,我試圖給它的JPEG格式。有沒有人有什麼建議?謝謝!!!

回答

1

連接兩種算法的關鍵思想:

#infinite loop 
#...stream reading operations 
if a!=-1 and b!=-1: 
    jpg = bytes[a:b+2] 
    bytes= bytes[b+2:] 
    img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.CV_LOAD_IMAGE_COLOR) 
    if cv2.waitKey(1) ==27: 
     exit(0) 
else: 
    continue 
cv.Smooth(img,img,cv.CV_BLUR,3) 
#... other tracker operations ... 

的imdecode功能「在存儲器中讀取來自緩衝器的圖像」。 QueryFrame從視頻捕捉設備讀取數據並返回一個圖像。 (「抓取,解碼並返回下一個視頻幀。」)因此,這兩種方法都會爲您提供一個圖像對象,但每個方法都來自不同的來源(相機與緩衝區)。而且圖像是您在跟蹤器中進一步處理所需的正確選擇!大多數OpenCV方法使用圖像作爲其固有的柵格數據格式。

管道比如下:從圖像文件或視頻捕獲幀/加載圖片 - > [圖像] - >處理,計算,閾值,輪廓等在圖像上完成 - >顯示結果或修改圖像 - >重複這個(永遠:-))。有關更多信息,請參閱http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html

+0

OP&@karlphilip嗨,謝謝你的回覆。我嘗試了這種方法,並被openCV告知img需要和openCVMat並使用cv.fromarray()來執行此操作。所以這就是我最終的結果:'cv.fromarray((img = cv2.imdecode(np.fromstring(jpg,dtype = np.uint8),cv2.CV_LOAD_IMAGE_COLOR)),allowND = False)'這隻顯示一個圖像然後它凍結。我認爲它會不斷地轉換圖像,因爲它被捕獲,但它似乎只捕獲一個圖像或凍結。有什麼建議麼??? – wunjo

0

檢查第一個源代碼,當執行cv2.imshow('i',i)時,網絡攝像頭圖像顯示在窗口上。

在這一點上,而不是顯示圖像,你應該使用算法從第二個代碼,它在img = cv.QueryFrame(capture)之後開始處理它。這意味着你不再需要這些行:

capture = CaptureFROMCAM(0) 

while True: 
img = cv.QueryFrame(capture)