OpenCV Python - Draw circle at random position in webcam video feed - python

I have the following code:
import cv2
from random import randrange
cap = cv2.VideoCapture(0) #record webcam
while True:
ret, frame = cap.read() #get feed from webcam
h, w = frame.shape[:2] #height, width
randomWidth = randrange(30,w-30)
randomHeight = randrange(70,h-30)
coordinates = (randomWidth, randomHeight)
circle = cv2.circle(frame, coordinates, 30, (0,0,255), -1) #circle
cv2.imshow('webcam', frame) #show webcam
if cv2.waitKey(1) == ord('q'): #press 'q' to close
break
cap.release()
cv2.destroyAllWindows()
My goal is to have the circle displayed at a random position every time I run the program. However, with this current code, the circle is jumping all over the screen, being drawn at a random position with every frame. How can I modify this code so that the circle is drawn at a random width and height and stays in that position until I exit the program?

You are recalculating the coordinates in each iteration, which is why the circle keeps moving around. You want to only calculate coordinates once and then keep using that value. Here is one way to do so:
import cv2
from random import randrange
cap = cv2.VideoCapture(0) #record webcam
ret, frame = cap.read() #get feed from webcam
h, w = frame.shape[:2] #height, width
randomWidth = randrange(30, w-30)
randomHeight = randrange(70, h-30)
coordinates = (randomWidth, randomHeight)
while True:
ret, frame = cap.read() #get feed from webcam
circle = cv2.circle(frame, coordinates, 30, (0,0,255), -1) #circle
cv2.imshow('webcam', frame) #show webcam
if cv2.waitKey(1) == ord('q'): #press 'q' to close
break
cap.release()
cv2.destroyAllWindows()
The frame is fetched once before the loop, used to get random coordinates and then the loop continues to update the frame with the circle being at fixed coordinates.
In case your requirement may involve a changing frame.shape or there is some situation where coordinates may need to be recalculated in the loop, using a condition like below can be more flexible because coordinates is None can be replaced with different criteria:
import cv2
from random import randrange
cap = cv2.VideoCapture(0) #record webcam
coordinates = None
while True:
ret, frame = cap.read() #get feed from webcam
if coordinates is None:
h, w = frame.shape[:2] #height, width
randomWidth = randrange(30, w-30)
randomHeight = randrange(70, h-30)
coordinates = (randomWidth, randomHeight)
circle = cv2.circle(frame, coordinates, 30, (0,0,255), -1) #circle
cv2.imshow('webcam', frame) #show webcam
if cv2.waitKey(1) == ord('q'): #press 'q' to close
break
cap.release()
cv2.destroyAllWindows()

Related

How do I add an image overlay to my live video using cv2?

This is my code, I've looked at some tutorials but can't find what I'm looking for
I want to overlay the Frame.png image on my webcam. I tried to add the image directly but it didn't work either. If possible, Is there a way to add an image, not to overlay but to keep the image at a certain coordinate in the live webcam window
import cv2
import numpy as np
def detect_and_save():
alpha = 0.2
beta = 1-alpha
cap = cv2.VideoCapture(0)
sciframe = cv2.imread('Frame.png')
classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
while True:
ret ,frame = cap.read()
overlay = frame.copy()
output = frame.copy()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = classifier.detectMultiScale(gray,1.5,5)
cv2.putText(output, "HUD Test",(175, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 50, 50), 3)
cv2
for face in faces:
x,y,w,h = face
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,200,0),-1)
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,0,0),1)
cv2.rectangle(overlay,(x,y-20),(x+w,y),(25,20,0),-1)
cv2.addWeighted(overlay,alpha,output,beta,0,output)
cv2.putText(output,"Human",(x+10,y-10),cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
if not ret:
continue
cv2.imshow("HUD",output)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite('./images/CID_{}.png'.format(time.strftime('%d%m%y_%H_%M_%S')),output)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
import time
detect_and_save()
You can directly add one image on top of another one at any coordinate easily in opencv.
cap = cv2.VideoCapture(0)
im_height = 50 #define your top image size here
im_width = 50
im = cv2.resize(cv2.imread("Frame.png"), (im_width, im_height))
while (True):
ret, frame = cap.read()
frame[0:im_width, 0:im_height] = im #for top-left corner, 0:50 and 0:50 for my image; select your region here like 200:250
cv2.imshow("live camera", frame)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()

How to display circle coordinates and borders in a video

I want to detect only the billiard balls inside the square, but circles in other places are also detected.
And the coordinates are not displayed as x and y, but 3 values, and the coordinates of the circle I want to take coordinates on do not come out well because the billiard ball is not recognized properly.
### file association
file = "C:\\Users\\woo\\Documents\\billiards_in.mp4"
cap = cv2.VideoCapture(file)
### video output
while True:
k = cv2.waitKey(10)
if k == ord("q"): break
### Capture frame-by-frame
ret, frame = cap.read()
if not ret: break
### Billiard Table Display - Rectangle
cv2.rectangle(frame, (250, 100), (1250, 600), (0, 255, 255), 2)
if ret:
# image processing
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
frame = cv2.GaussianBlur(frame,(0,0),1)
circles = cv2.HoughCircles(frame, cv2.HOUGH_GRADIENT,1,50,
param1= 150, param2= 40, minRadius= 1, maxRadius= 100)
circle = np.uint16(np.around(circles))
for cx,cy,radius in circles[0,:]:
### circle sign
cv2.circle(frame,(cx,cy),int(radius),(0,255,255),2)
### ball coordinate display
cv2.putText(frame,str(circles),(cx,cy),cv2.FONT_HERSHEY_SIMPLEX,0.75,(255,0,0),2,cv2.LINE_AA)
else:
print("Can't receive frame. Exiting...")
break
### frame output
cv2.imshow("VideoFrame", frame)
### When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Do you know what's wrong with my code??
(+ I want to upload the mp4 file used in the code, but I don't know how to upload it..)

Rotate video 180 with OpenCV Python

I'm a python beginner so sorry in advance for the mistakes.
I'm trying to rotate a video 180 degrees and then work with that video that I should have created.
At the moment I'm doing this:
import cv2
import numpy as np
#that's my original video - the one that I want to rotate 180 degrees
cap = cv2.VideoCapture('/Users/name/Desktop/VIDEO 12.05/PIC_P01.mp4')
frame_number = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# Original Frames
frames = []
for i in range(frame_number):
ret, frame = cap.read()
frames.append(frame)
#here's where I try to rotate the video
new = cv2.rotate(frame, cv2.ROTATE_180)
cv2.imshow('output', new)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#here I'm trying to write the new rotated video
newvideoR = cv2.VideoWriter('PIC_P01R.mp4',0x7634706d, 50, (360, 640))
for jj in range(len(new)):
newvideoR.write(new[jj])
newvideoR.release()
cap.release()
In the end, however, when I go to read the file I find only an empty file that I cannot open.
From this, I deduce that there is an error in the steps that I have made.
Would anyone have any advice on how am I suppose to do this?
** I've also tried to change the parameter on cv2.Videowriter (for example fps, size) but is still not working
You don't need to accumulate the frames, and write them in another loop.
You can read a frame, rotate it, and write it in the same loop.
Get width and height:
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
Open the output video file before the loop:
newvideoR = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*"mp4v"), 50, (frame_width, frame_height))
Read the frame, rotate it and write it in a loop:
for i in range(frame_number):
ret, frame = cap.read()
new = cv2.rotate(frame, cv2.ROTATE_180)
cv2.imshow('output', new)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
newvideoR.write(new)
Release video reader and writer:
newvideoR.release()
cap.release()
Complete code sample (I named the files input.mp4 and output.mp4):
import cv2
#that's my original video - the one that I want to rotate 180 degrees
cap = cv2.VideoCapture('input.mp4')
frame_number = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# Get width and height
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# here I'm trying to write the new rotated video
# Open the output video file before the loop, cv2.VideoWriter_fourcc(*"mp4v") = 0x7634706d
newvideoR = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*"mp4v"), 50, (frame_width, frame_height))
# Original Frames
#frames = []
for i in range(frame_number):
ret, frame = cap.read()
#frames.append(frame) # No need to append the original frames
#here's where I try to rotate the video
new = cv2.rotate(frame, cv2.ROTATE_180)
cv2.imshow('output', new)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
newvideoR.write(new)
newvideoR.release()
cap.release()

Histogram of my cam in real time

Im trying to show the histogram in real time from grayscale of my webcam, the problem is that histogram is not being update and my cam stop until i close histogram's window. How can i fix this? I want to show the grayscale img from my webcam and its histogram in same time, is possible do that?
import numpy as np
import cv2
from matplotlib import pyplot as plt
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Janela', frame)
cv2.imshow('Outra', gray)
plt.hist(gray.ravel(), 256, [0, 256])
plt.show()
if (cv2.waitKey(1) & 0xFF == 27):
break
cap.release()
cv2.destroyAllWindows()
I have been working for a while in the same task. After some time, I have a piece of code that works very good. It displays the camera image in a window and a histogram in other. Since I'm interested in finding colors, I'm working with the "hue" channel of each frame.
# import the necessary packages
import cv2
import numpy as np
#Create window to display image
cv2.namedWindow('colorhist', cv2.WINDOW_AUTOSIZE)
#Set hist parameters
hist_height = 64
hist_width = 256
nbins = 32
bin_width = hist_width/nbins
camera_id = 0 # type fo webcam [0 built-in | 1 external]
cameraWidth = 320
cameraHeight = 240
if camera_id == 0:
cameraId = "PC webcam"
elif camera_id == 1:
cameraId = "External webcam"
camera = cv2.VideoCapture(camera_id)
# set camera image to 320 x 240 pixels
camera.set(3,cameraWidth)
camera.set(4,cameraHeight)
cameraInfo = "Image size (%d,%d)" % (camera.get(3),camera.get(4))
# initialize mask matrix
mask = np.zeros((cameraHeight,cameraWidth), np.uint8)
# draw a circle in mask matrix
cv2.circle(mask,(cameraWidth/2,cameraHeight/2), 50, 255, -1)
#Create an empty image for the histogram
h = np.zeros((hist_height,hist_width))
#Create array for the bins
bins = np.arange(nbins,dtype=np.int32).reshape(nbins,1)
while True:
# grab the current frame
(grabbed, frame) = camera.read()
if not grabbed:
"Camera could not be started."
break
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
#Calculate and normalise the histogram
hist_hue = cv2.calcHist([hsv],[0],mask,[nbins],[0,256])
cv2.normalize(hist_hue,hist_hue,hist_height,cv2.NORM_MINMAX)
hist=np.int32(np.around(hist_hue))
pts = np.column_stack((bins,hist))
#Loop through each bin and plot the rectangle in white
for x,y in enumerate(hist):
cv2.rectangle(h,(x*bin_width,y),(x*bin_width + bin_width-1,hist_height),(255),-1)
#Flip upside down
h=np.flipud(h)
#Show the histogram
cv2.imshow('Color Histogram',h)
h = np.zeros((hist_height,hist_width))
frame = cv2.bitwise_and(frame,frame,mask = mask)
cv2.putText(frame, cameraInfo, (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow(cameraId, frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key is pressed, break from the loop
if key == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
The code is based on the code from JohnLinux post (How do I plot a 32-Bin Histogram for a Grayscale Image in Python using OpenCV) and other lines of code come from what I have learnt from Adrian Rosenbrock's site https://www.pyimagesearch.com/.
I see there is very little feedback on this topic. Some solutions look overwhelmingly complex. My brother needed just a simple version of such programme for his studies, so I decided to write it as simple as it can be (11 lines of code - enjoy:))
import cv2 as cv
from matplotlib import pyplot as plt
vid = cv.VideoCapture(0, cv.CAP_DSHOW)
while True:
ret, img = vid.read()
cv.imshow("img", img)
plt.hist(img.ravel(), 256, [0, 256])
plt.draw()
plt.pause(0.1)
plt.clf()
cv.destroyAllWindows()
another solution for the picamera doing stream + histogram
from picamera import PiCamera
from picamera.array import PiRGBArray
import cv2
import matplotlib.pyplot as plt
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 40
rawCapture = PiRGBArray(camera, size=(640, 480))
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
bgr_arr = frame.array
gray_arr = cv2.cvtColor(bgr_arr, cv2.COLOR_BGR2GRAY)
cv2.imshow("Preview", gray_arr)
key = cv2.waitKey(1) & 0xFF
rawCapture.truncate(0)
plt.hist(gray_arr.ravel(), 256, [0, 256], histtype='stepfilled')
plt.title('Grayscale histogram')
plt.xlabel('Grayscale value')
plt.ylabel('Pixel count')
plt.plot()
plt.pause(0.1)
plt.clf()
if key == ord("q"):
cv2.destroyAllWindows()
break

track a image in video and replace with another image using opencv

I have to track a window in a video and need to paste an image on window,I have used camshift to track the window, but it did not track it correct.My window is in brown color so I have given the following color range.
np.array((110,0,0)--lower
np.array((130,255,255)--higher..
I have red many documents in opencv but not able to figure out which method to follow.I am using opencv2.4.9 with python.
Below is the code which I tried.Please help me out to figure out the exact location of window.emphasized text
#!/usr/bin/env python
import numpy as np
import cv2
cap = cv2.VideoCapture("myvideo.mp4")
# take first frame of the video
ret,frame = cap.read()
#print frame
#print ret
# setup initial location of window
r,h,c,w = 157,40,337,40
track_window = (c,r,w,h)
# set up the ROI for tracking
roi = frame[r:r+h, c:c+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((110,0,0)), np.array((130,255,255)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[255],[0,255])
cv2.imshow('img2',roi_hist)
#print roi_hist
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
# Setup the termination criteria, either 10 iteration or move by at least 1 pt
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
i = 1
while(1):
ret ,frame = cap.read()
if ret == True:
i += 1
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,255],1)
# apply meanshift to get the new location
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
#print track_window
# Draw it on image
x,y,w,h = track_window
img2 = cv2.rectangle(frame, (x,y), (x+w,y+h), 255,2)
cv2.imshow('img2',frame)
k = cv2.waitKey(200) & 0xff
if k == 27:
break
else:
# print "comes here2";
cv2.imwrite(str(i)+"test.jpg",frame)
#break
else:
break
cv2.destroyAllWindows()
cap.release()

Categories

Resources