Repository: opencv
Issue: BUG in cv2.VideoCapture()
Labels: category: videoio,category: 3rdparty

Hello there,

We are using Milestone systems Open Network Bridge to access live vide stream from IP cameras connected to Milestone Video Management System. This bridge is ONVIF compliant interface that streams video from any camera in the Milestone system over RTSP to third party applications. Actually, it is a single point where any video stream from any IP camera in the system can be access from third party applications.  

We have managed to connected VLC and number or ONVIF video players to this bridge by using Bridge network url. But with OpenCV, Python and cv2.VideoCapture() we cannot get video stream. 

This is a message that we receive:
 _[rtsp @ 00000131146d2d80] method DESCRIBE failed: 401 Unauthorized_

We have analyzed RTSP traffic with Wireshark and find out that cv2.VideoCapture() as a RTSP Client is not sending Authorization request to RTSP server. 

This field is missing in RTSP packed from cv2.VideoCapture().
_Authorization: Digest username="onvif_user1", realm="RtspServerLibrary", nonce="GAtwvF0Jm7WYCqsPpCFO0RVr4VJXtYNx", uri="rtsp://192.168.178.32:554/live/8bdb948f-d5d0-4cab-bea6-ffe92089be45", response="e0442992fe8b83d0b77e00c29549bc34"\r\n_

**Why do we think that this is a BUG in OpenCV and not in Milestone Systems - Open Network Bridge.**
This is a replay that we get when we are want to connect to IP video camera from our python program
_WWW-Authenticate: Digest realm="AXIS_ACCC8E82812B", nonce="0004326fY64840928ff07585665e8b4cbd1d56c8cdf7dcd", stale=FALSE\r\n
WWW-Authenticate: Basic realm="AXIS_ACCC8E82812B"\r\n_
After this reply cv2.VideoCapture() is sending authorization to video camera and video camera starts to stream live video.
[_truncated]Authorization: Digest username="root", realm="AXIS_ACCC8E82812B", nonce="0004326fY64840928ff07585665e8b4cbd1d56c8cdf7dcd", uri="rtsp://192.168.178.27:554//axis-media/media.amp?camera=3&resolution=1920x1080", response="d8aa0128_
When we try to connect to Milestone Bridge with the same Python program we get the following reply:
_WWW-Authenticate: Digest realm="RtspServerLibrary", nonce="PFt4sIAXJ9FrsMYBgzU5NzTiX69Q957q", algorithm="MD5"\r\n
WWW-Authenticate: Digest realm="RtspServerLibrary", nonce="PFt4sIAXJ9FrsMYBgzU5NzTiX69Q957q", algorithm="SHA-256"\r\n_
After this reply cv2.VideoCapture() is NOT sending authorization to Milestone Bridge in RTSP DESCRIBE Method. BUT VLC player does, and VLC player starts to stream live video from Milestone Bridge. 
Here is the response from VLC player:
_Authorization: Digest username="onvif_user1", realm="RtspServerLibrary", nonce="GAtwvF0Jm7WYCqsPpCFO0RVr4VJXtYNx", uri="rtsp://192.168.178.32:554/live/8bdb948f-d5d0-4cab-bea6-ffe92089be45", response="e0442992fe8b83d0b77e00c29549bc34"\r\n_

Feel free to contact us for any questions,

Best regards,
Hrvoje Bilic



Python code:
```
import cv2
import numpy as np
import math

#Open Bridge Network
_CONNSTR = "rtsp://onvif_user1:13VisionD@192.168.178.32:554/live/8bdb948f-d5d0-4cab-bea6-ffe92089be45"
cap=cv2.VideoCapture(_CONNSTR)

#Video camera
#cap=cv2.VideoCapture('rtsp://root:kpk3mmx1HB@192.168.178.27//axis-media/media.amp?camera=3&resolution=640x480')


cap.set(cv2.CAP_PROP_BUFFERSIZE, 3)

ret, frame1=cap.read()

#Ako je ret=true onda onda ulazni buffer ima frame
if ret:
    frame1=cv2.resize(frame1,(640,480),fx=0,fy=0, interpolation = cv2.INTER_CUBIC)

ret, frame2=cap.read()
#Ako je ret=true onda onda ulazni buffer ima frame
if ret:
    frame2=cv2.resize(frame2,(640,480),fx=0,fy=0, interpolation = cv2.INTER_CUBIC)


i=0
while cap.isOpened():

    diff=cv2.absdiff(frame1, frame2)
    gray=cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
    blur=cv2.GaussianBlur(gray,(9,9),0)
    _,thresh=cv2.threshold(blur,10,255,cv2.THRESH_BINARY)
    dilated=cv2.dilate(thresh, None,iterations=3)
    #contours,_=cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    contours,hierarchy=cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    cv2.drawContours(frame1, contours, -1, (0, 255, 0), 1)

    cv2.imshow("Frame_Diff", frame1)
    #cv2.moveWindow("Frame_Diff",0,0)

    frame1=frame2
    ret, frame2= cap.read()

    if ret:
    #if frame2 is not None:
        frame2=cv2.resize(frame2,(640,480),fx=0,fy=0, interpolation = cv2.INTER_CUBIC)


    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()
cap.release()
```