首页 > 解决方案 > 为什么 OpenCV-Java 无法连接到 mjpeg-stream(来自烧瓶)而 Python3/cv2 可以做到?

问题描述

Python/flask 服务器 (server.py) 充当 WebCam 代理。

注意:虽然 cv2.open(url) 只发送一个 GET 请求。使用 Java/OpenCV,服务器看到 2 个 GET 请求并且捕获保持关闭。

下面是源代码和命令行调用……在 Win7Pro 上运行。

有什么想法为什么它不能在 Java 中工作?

服务器.py

# Python 3.7.4 / cv2.__version__=4.1.1
# WebCam-Server providing MJPEG stream
#   OK:Firefox_62.0.3   OK_SLOW:VLC_3.0.8   OK:Py3.7+cv2
#   FAIL:Java+OpenCV_4.1.1

# python server.py

import cv2, time
from flask import Flask, Response, request

VIDEO_CAPTURE_ID=0
app=Flask(__name__)

def get_frames():
  camera=cv2.VideoCapture(VIDEO_CAPTURE_ID, cv2.CAP_DSHOW)
  while True:
    val, img=camera.read()
    if not val: continue
    yield cv2.imencode('.jpg', img)[1].tobytes()
    time.sleep(0.01)

def gen():
  while True:
    for frame in get_frames():
      yield (b'--frame\r\n'
             b'Content-Type:image/jpeg\r\n'
             b'Content-Length: '+(b'%d' % len(frame))+b'\r\n'
             b'\r\n'+frame+b'\r\n')

@app.route('/videofeed')
def f_videofeed():
  print("@app.route('/videofeed') .....")
  return Response(gen(), mimetype='multipart/x-mixed-replace;boundary=frame')

if __name__=='__main__':
  app.run(host='localhost', threaded=True, debug=True) # default port 5000

客户端.py

# Python 3.7.4 / cv2.__version__=4.1.1
# Client ... 

# python client.py

client.py
import cv2
fg=cv2.VideoCapture()
print(fg)
addr="http://localhost:5000/videofeed?cam.mjpg"
print(addr)
tst=fg.open(addr)
print(tst)
for ii in range(5):
  val,frm=fg.read()
  s1=frm.tostring()
  print("%d : %r  %r  %r ... %r" % (ii, val, len(s1), s1[:6], s1[-6:]))
fg.release()

客户端.java

// Java 1.8.0_192 / opencv-4.1.1_vc14_vc15
// Client
//     opencv-411.jar/opencv_java411.dll vom InstallDir nach "." kopiert

// javac -cp opencv-411.jar client.java && java.exe -cp .;opencv-411.jar client

import org.opencv.core.Core;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;

public class client{
  public static void main (String args[]) throws InterruptedException
  {
    Boolean tst=false;
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    VideoCapture fg=new VideoCapture(Videoio.CAP_FFMPEG);
    System.out.println(fg);
    String addr="http://localhost:5000/videofeed?cam.mjpg";
    tst=fg.open(addr);
    System.out.println(tst);
    System.out.println(fg.getBackendName());
  }
}

客户端控制台窗口

test_flask_opencv>
test_flask_opencv>javac -cp opencv-411.jar client.java && java.exe -cp .;opencv-411.jar client
org.opencv.videoio.VideoCapture@28d93b30
[ERROR:0] global C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap.cpp (116) cv::VideoCapture::open VIDEOIO(CV_IMAGES): raised OpenCV exception:

OpenCV(4.1.1) C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): http://localhost:5000/videofeed?cam.mjpg in function 'c
v::icvExtractPattern'


false
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.1.1) C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap.cpp:220: error: (-215:Assertion failed) api != 0 in function 'cv::VideoCap
ture::getBackendName'
]
        at org.opencv.videoio.VideoCapture.getBackendName_0(Native Method)
        at org.opencv.videoio.VideoCapture.getBackendName(VideoCapture.java:164)
        at client.main(client.java:23)

test_flask_opencv>
test_flask_opencv>
test_flask_opencv>python client.py
<VideoCapture 0013DDC0>
http://localhost:5000/videofeed?cam.mjpg
True
FFMPEG
0 : True  921600  b'\x00\x00\x00\x00\x00\x00' ... b'\x00\x00\x00\x00\x00\x00'
1 : True  921600  b'\x9e\xa9\x8c\x9a\xa5\x88' ... b'`vok\x81z'
2 : True  921600  b'\xc3\xa3\x91\xc1\xa1\x8f' ... b'\x90\x80\x85\x8d}\x82'
3 : True  921600  b'\xb4\x9d\x8f\xb0\x99\x8b' ... b'\x9d\x90\x8c\x8f\x82~'
4 : True  921600  b'\xcd\x94\x86\xd2\x99\x8b' ... b'\xb8\x89\x85\xac}y'

test_flask_opencv>

服务器控制台窗口

test_flask_opencv>
test_flask_opencv>python server.py
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 156-364-938
 * Running on http://localhost:5000/ (Press CTRL+C to quit)
@app.route('/videofeed') .....
127.0.0.1 - - [10/Nov/2019 17:45:44] "GET /videofeed?cam.mjpg HTTP/1.1" 200 -
@app.route('/videofeed') .....
127.0.0.1 - - [10/Nov/2019 17:45:45] "GET /videofeed?cam.mjpg HTTP/1.1" 200 -

test_flask_opencv>
test_flask_opencv>
test_flask_opencv>
test_flask_opencv>python server.py
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 156-364-938
 * Running on http://localhost:5000/ (Press CTRL+C to quit)
@app.route('/videofeed') .....
127.0.0.1 - - [10/Nov/2019 17:46:17] "GET /videofeed?cam.mjpg HTTP/1.1" 200 -

标签: javapythonopencvwebcammjpeg

解决方案


推荐阅读