Could not write and save live video using OpenCV - python

I am trying to write and save the video of my object detection. I have referred and tried based on the posts posted here in Stackoverflow. However, none of them is working.
My specifications:
Python 3.7.9
OpenCV 4.5.1
The code is as below
import cv2
from main import *
import imutils
import math
darknetmain = darknet_main()
darknetmain.setGPU(is_GPU=True)
saveVid ="./data/test_sampah_tasik.mp4"
video = cv2.VideoCapture(0)
width = 270
height = 480
size = (width,height)
result = cv2.VideoWriter('21_output.mpeg',cv2.VideoWriter_fourcc(*'MPJG'),20,size)
# initialize the known distance from the camera to the object, which
# in this case is 24 inches
KNOWN_DISTANCE = 12.0
# initialize the known object width, which in this case, the piece of
# paper is 11.81 inches wide
KNOWN_WIDTH = 12.0
if video.isOpened():
while(True):
res, cv_img = video.read()
if res==True:
k = cv_img[90:360, 90:570]
imcaptions, boundingBoxs = darknetmain.performDetect(k)
if len(imcaptions)>0:
for i in range(len(imcaptions)):
k = cv2.rectangle(k, boundingBoxs[i][0], boundingBoxs[i][2], (0, 255, 0), 2)
k = cv2.putText(k, imcaptions[i], boundingBoxs[i][0], cv2.FONT_HERSHEY_SIMPLEX, 1,
(0, 0, 255))
startPoint = (180,570)
dividePoint = [x for x in boundingBoxs[i][2]]
dividePoint[0] = dividePoint[0] - 50
dividePoint[1] = dividePoint[1] - 50
if dividePoint[0] > 160:
print("Right")
elif dividePoint[0] <= 160:
print("Left")
centerPoint= (int(dividePoint[0]),int(dividePoint[1]))
k = cv2.line(k, startPoint, centerPoint, (0, 255, 0), 2)
result.write(k)
cv2.imshow("result", k)
else:
#print("no result")
result.write(k)
cv2.imshow("result", k)
key = cv2.waitKey(1)
if key==27 or 0xFF == ord('q'):
break
else:
break
else:
print("Cannot read the video file")
The error that I received is
OpenCV: FFMPEG: tag 0x4745504d/'MPEG' is not supported with codec id 2 and format 'mpeg / MPEG-1 Systems / MPEG program stream'

Related

i am working on program which select's the ROI of wobbly video and extract the ROI in diff window as stable ROI, want to improve its computation speed

The problem is, program is really lengthy and computationally expensive.
so is there any way to make this program faster or any other way to write this code?
I am beginner in python and would love to take all suggestions or different approach then this program
also i am new to the stack overflow so if anything is wrong in this post or any issue in program please point out in comment .
first section of code is
#TEST V2.1 multitracker
import cv2
import numpy as np
#path = (input("enter the video path: "))
cap = cv2.VideoCapture(" YOUR VIDEO PATH ")
# creating the dictionary to add all the wanted trackers in OpenCV that can be used for tracking in future
OBJECT_TRACKING_MACHINE = {
"csrt": cv2.legacy.TrackerCSRT_create,
"kcf": cv2.legacy.TrackerKCF_create,
"boosting": cv2.legacy.TrackerBoosting_create,
"mil": cv2.legacy.TrackerMIL_create,
"tld": cv2.legacy.TrackerTLD_create,
"medianflow": cv2.legacy.TrackerMedianFlow_create,
"mosse": cv2.legacy.TrackerMOSSE_create
}
# Creating the MultiTracker variable object to store the
trackers = cv2.legacy.MultiTracker_create()
here I started the loop
while True:
frame = cap.read()[1]
#print("freame start",frame)
if frame is None:
print("error getting the video,please check the input")
break
frame = cv2.resize(frame,(1080,720))
Thresh = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#Thresh = cv2.adaptiveThreshold(gray, 185, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV, 11, 6)
#print(trackers.update(Thresh))
(success, boxes) = trackers.update(Thresh)
# loop over the bounding boxes and draw them on the frame
if success == False:
bound_boxes = trackers.getObjects()
idx = np.where(bound_boxes.sum(axis= 1) != 0)[0]
bound_boxes = bound_boxes[idx]
trackers = cv2.legacy.MultiTracker_create()
for bound_box in bound_boxes:
trackers.add(tracker,Thresh,bound_box)
x,y,w,h = cv2.boundingRect(Thresh)
k = cv2.waitKey(50)
And I am guessing this is the section which is making the program slow
if is there any different way to represent this part or any idea different then this
for i,box in enumerate(boxes):
(x, y, w, h) = [int(v) for v in box]
#cv2.rectangle(Thresh, (x, y), (x + w, y + h), (255, 255, 255), 2)
#cv2.putText(Thresh,('TRACKING BOX NO-'+str(i)),(x+10,y-3),cv2.FONT_HERSHEY_PLAIN,1.0,(255,255,0),2)
arr = boxes.astype(int)
if i == 0 :
Roi = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
murg = cv2.resize(Roi,(300,200))
cv2.imshow("horizon", murg)
#print(murg)
if i == 1 :
Roi1 = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
Roi = Thresh[(arr[(i-1),1]):(arr[(i-1),1]+arr[(i-1),3]),(arr[(i-1),0]):(arr[(i-1),0]+arr[(i-1),2])]
murg = cv2.resize(Roi,(300,200))
murg1 = cv2.resize(Roi1,(300,200))
hori = np.concatenate((murg,murg1),axis=1)
cv2.imshow("horizon",hori)
#print(hori)
elif i == 2 :
Roi2 = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
Roi1 = Thresh[(arr[(i-1),1]):(arr[(i-1),1]+arr[(i-1),3]),(arr[(i-1),0]):(arr[(i-1),0]+arr[(i-1),2])]
Roi = Thresh[(arr[(i-2),1]):(arr[(i-2),1]+arr[(i-2),3]),(arr[(i-2),0]):(arr[(i-2),0]+arr[(i-2),2])]
murg = cv2.resize(Roi,(300,200))
murg1 = cv2.resize(Roi1,(300,200))
murg2 = cv2.resize(Roi2,(300,200))
hori = np.concatenate((murg,murg1,murg2),axis=1)
cv2.imshow("horizon",hori)
#print(hori)
elif i == 3 :
Roi3 = Thresh[(arr[i,1]):(arr[i,1]+arr[i,3]),(arr[i,0]):(arr[i,0]+arr[i,2])]
Roi2 = Thresh[(arr[(i-1),1]):(arr[(i-1),1]+arr[(i-1),3]),(arr[(i-1),0]):(arr[(i-1),0]+arr[(i-1),2])]
Roi1 = Thresh[(arr[(i-2),1]):(arr[(i-2),1]+arr[(i-2),3]),(arr[(i-2),0]):(arr[(i-2),0]+arr[(i-2),2])]
Roi = Thresh[(arr[(i-3),1]):(arr[(i-3),1]+arr[(i-3),3]),(arr[(i-3),0]):(arr[(i-3),0]+arr[(i-3),2])]
murg = cv2.resize(Roi,(300,200))
murg1 = cv2.resize(Roi1,(300,200))
murg2 = cv2.resize(Roi2,(300,200))
murg3 = cv2.resize(Roi3,(300,200))
hori = np.concatenate((murg,murg1,murg2,murg3),axis=1)
cv2.imshow("horizon",hori)
#print(hori)
this section is so that I can print the ROI matrix and to select the ROI
if k == ord("1"):
print(murg)
if k == ord("2"):
print(murg1)
if k == ord ("3"):
print(murg2)
if k == ord("4"):
print(murg3)
cv2.imshow('Frame', Thresh)
if k == ord("e"):
break
if k == ord("s"):
roi = cv2.selectROI("Frame", Thresh, fromCenter=False,showCrosshair=False)
tracker = OBJECT_TRACKING_MACHINE['mosse']()
trackers.add(tracker, Thresh, roi)
#print(boxes,success)
cap.release()
cv2.destroyAllWindows()
when you will run this code you can extract 4 ROI frames which will track your ROI's (I haven't added the precaution for empty matrix so it will give you error if you select more than 4 roi's)
my end goal is to extract those ROI videos for Image processing (this code is not done yet and there's more image processing is going to happen in letter part) **

Python, cvzone - why do i get this ValueError?

I am trying to zoom into a picture with usage of two hands (gesture controled image zoom), but when trying to use two hands I get this error but I don't know why. When making my program I followed this tutorial: https://www.youtube.com/watch?v=VPaFV3QBsEw&t=675s. It's strange because the program worked for him.
This is the error I get:
hands, img = detector.findHands(img)
ValueError: too many values to unpack (expected 2)
This is my code:
import cv2
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0)
cap.set(3, 1280)
cap.set(4, 720)
detector = HandDetector(detectionCon=0.7)
startDist = None
scale = 0
cx, cy = 500,500
while True:
success, img = cap.read()
hands, img = detector.findHands(img)
img1 = cv2.imread("kung_fu_panda.png")
if len(hands) == 2:
if detector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] and \
detector.fingersUp(hands[1]) == [1, 1, 0, 0, 0]:
lmList1 = hands[0]["lmList"]
lmList2 = hands[1]["lmList"]
# point 8 is the tip of the index finger
if startDist is None:
length, info, img = detector.findDistance(hands[0]["center"], hands[1]["center"], img)
startDist = length
length, info, img = detector.findDistance(hands[0]["center"], hands[1]["center"], img)
scale = int((length - startDist) // 2)
cx, cy = info[4:]
print(scale)
else:
startDist = None
try:
h1, w1, _= img1.shape
newH, newW = ((h1+scale)//2)*2, ((w1+scale)//2)*2
img1 = cv2.resize(img1, (newW,newH))
img[cy-newH//2:cy+ newH//2, cx-newW//2:cx+ newW//2] = img1
except:
pass
cv2.imshow("Image", img)
cv2.waitKey(1)
cvzone library keeps updating their library every time. As you can see at the beginning of the video, when he imports the cvzone package he uses cvzone version 1.5.0.
I tried your code with other versions and got an error similar to yours but with version 1.5.0 your code worked great.
you can use my answer here to change the version of your cvzone library in your project to 1.5.0.

Python not responding when using face_recognition library

KNOWN_FACES_DIR = 'Known'
TOLERANCE = 0.6
FRAME_THICKNESS = 3
FONT_THICKNESS = 2
MODEL = 'cnn'
video=cv2.VideoCapture(0)
print('Loading known faces...')
known_faces = []
known_names = []
for name in os.listdir(KNOWN_FACES_DIR):
for filename in os.listdir(f'{KNOWN_FACES_DIR}/{name}'):
image = face_recognition.load_image_file(f'{KNOWN_FACES_DIR}/{name}/{filename}')
encoding = face_recognition.face_encodings(image)[0]
known_faces.append(encoding)
known_names.append(name)
while True:
ret,image=video.read()
locations = face_recognition.face_locations(image, model=MODEL)
encodings = face_recognition.face_encodings(image, locations)
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
print(f', found {len(encodings)} face(s)')
for face_encoding, face_location in zip(encodings, locations):
results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
match = None
if True in results:
match = known_names[results.index(True)]
print(f' - {match} from {results}')
top_left = (face_location[3], face_location[0])
bottom_right = (face_location[1], face_location[2])
cv2.rectangle(image, top_left, bottom_right,FRAME_THICKNESS)
top_left = (face_location[3], face_location[2])
bottom_right = (face_location[1], face_location[2] + 22)
cv2.rectangle(image, top_left, bottom_right,cv2.FILLED)
cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), FONT_THICKNESS)
cv2.imshow(filename, image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video.release()
cv2.destroyAllWindows()
I am using the face_recognition library for the face recognition project. This gives me the desired result but it keeps on not responding. It shows the result on a single frame after not responding for 20-30 sec. Is it because my laptop specs are not good or the code requires some changes?
https://www.youtube.com/watch?v=PdkPI92KSIs&list=RDCMUCfzlCWGWYyIQ0aLC5w48gBQ&index=2
This is the youtube video on how the result should look like.
Why don't you use deepface? Here, database path is the location where you stored facial images.
#!pip install deepface
from deepface import DeepFace
DeepFace.stream(db_path = "C:/my_db")

Getting this error "ValueError: not enough values to unpack (expected 3, got 2)" while compiling opencv contours

I'm going to run an openCV people counting tutorial code. tutorials are available here. https://fedemejia.com/?p=68
but while i'm running the following code by cmd. I'm getting this error
File "VideoCapture.py", line 25, in
_, contours0, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
ValueError: not enough values to unpack (expected 3, got 2)
my python version is 3.6.8
opencv 4.0.0
import numpy as np
import cv2
cap = cv2.VideoCapture('peopleCounter.avi') #Open video file
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows = True) #Create the background substractor
kernelOp = np.ones((3,3),np.uint8)
kernelCl = np.ones((11,11),np.uint8)
areaTH = 500
while(cap.isOpened()):
ret, frame = cap.read() #read a frame
fgmask = fgbg.apply(frame) #Use the substractor
try:
ret,imBin= cv2.threshold(fgmask,200,255,cv2.THRESH_BINARY)
#Opening (erode->dilate) para quitar ruido.
mask = cv2.morphologyEx(imBin, cv2.MORPH_OPEN, kernelOp)
#Closing (dilate -> erode) para juntar regiones blancas.
mask = cv2.morphologyEx(mask , cv2.MORPH_CLOSE, kernelCl)
except:
#if there are no more frames to show...
print('EOF')
break
_, contours0, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in contours0:
cv2.drawContours(frame, cnt, -1, (0,255,0), 3, 8)
area = cv2.contourArea(cnt)
print area
if area > areaTH:
#################
# TRACKING #
#################
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
x,y,w,h = cv2.boundingRect(cnt)
cv2.circle(frame,(cx,cy), 5, (0,0,255), -1)
img = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('Frame',frame)
#Abort and exit with 'Q' or ESC
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release() #release video file
cv2.destroyAllWindows() #close all openCV windows
It was supposed to give the result describe in the tutorial.
In OpenCV 4.0, cv2.findContour() returns only 2 values. So it should be contours0, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE). See here https://docs.opencv.org/master/df/d0d/tutorial_find_contours.html

txt file won't be written in python in windows, it works on mac

I wrote a code that takes a video and recognizes face of a human and calculate the distance of the human from the camera (which is the eye of a robot). I need the data in a txt format so I am writing it in the distance_data.txt but my file is always empty.
I had run the code in a mac computer and it worked perfectly fine and the file was not empty.
import cv2
import time
import numpy as np
person_cascade = cv2.CascadeClassifier('human_recognition.txt')
cap = cv2.VideoCapture('oct23_2.avi')
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('oct23_2out.avi',fourcc, 20.0, (640,360))
distance_data = open('distance_data.txt','w')
timer=-1
while (cap.isOpened()):
r, frame = cap.read()
if r:
frame = cv2.resize(frame,(640,360)) # Downscale to improve frame rate
gray_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # Haar-cascade classifier needs a grayscale image
cv2.imshow('gray',gray_frame)
#print(gray_frame.type())
rects = person_cascade.detectMultiScale(gray_frame)
max=0
#print(rects)
(x, y, w, h) = rects[0]
cv2.rectangle(frame, (x,y), (x+w ,y+h),(0,255,0),2)
#fshape = frame.shape
#fheight = fshape[0]
#fwidth = fshape[1]
timer=timer+1
xpos=(0.03421)*(w*w)-8.1183*w+521.841
yn=360-y
heightinvid=0.0197377*yn-0.0194
realhieght=((-0.4901)*(heightinvid* heightinvid)+4.4269*heightinvid+8.30356)/ 0.927183854
horizontalp=x+w/2
#print(timer+1 , ",", xpos, )
#if (xpos<=41 and xpos>=40):
#print("height of the human is ", realhieght+149, "or", (-0.000184)*yn*yn+0.08506*yn+8.43461+149)
cm_deviation_in_x=-0.02033898*(320-horizontalp)
#print("Horizontal position of human is ", cm_deviation_in_x, " cm.")
newxpos = format (xpos, '.3f')
distance_data.write("Hi")
distance_data.write(str(newxpos))
distance_data.write(',')
distance_data.write(str(format(cm_deviation_in_x, '.3f')))
distance_data.write("\r\n")
#print(w)
#print("x position of the human is = ",xpos)
#fourcc = cv2.VideoWriter_fourcc(*'XVID')
#out = cv2.VideoWriter('output25.avi',fourcc, 20.0, (fwidth,fheight))
cv2.imshow("preview", frame)
out.write(frame)
k = cv2.waitKey(10)
#print(w,h)
if k & 0xFF == ord("q"): # Exit condition
break
distance_data.flush()
cap.release()
cv2.destroyAllWindows()

Categories

Resources