2014-07-18 106 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)