Python code to capture present frame and kill past frames. - python

I am writing code to extract text from live video. I write the code and it,s executing well. But the problem is that it is taking all the frames and running slowly. Means giving delay of 10 seconds. Is there any command to kill past frames and take present frame for processing.
import cv2
import numpy as np
import time
import math
from PIL import Image
from pytesseract import image_to_string
cap = cv2.VideoCapture(0)
while(True):
cap.open
ret, img = cap.read()
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
kernel = np.ones((1, 1), np.uint8)
img = cv2.dilate(img, kernel, iterations=1)
img = cv2.erode(img, kernel, iterations=1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow('frame', th3)
text = image_to_string(th3)
print text
if cv2.waitKey(1) & 0xFF == ord('q'):
out = cv2.imwrite('capture.jpg', frame)
break
cap.release()
cv2.destroyAllWindows()

Not exactly.
VideoCapture works by giving you the next frame to process in order. If it is slow, it is up to you to process it or not.
One common solution is just process every i frames.
But you can also change the Frame Per Seconds rate with:
cap.set(cv2.CAP_PROP_FPS, 10)

Related

How to remove noise from CLAHE, Python?

I was trying to figure out a way to read the veins in an video capture (i am using special camera) using OpenCV in Python, but there are too many noise from the results i got. Can someone help?
here is the result: https://ibb.co/cbdxY5F
i want all in the red circle to be clear without nosie: https://ibb.co/C9SPjyX
import cv2
import numpy as np
import time
def multi_clahe(img, num):
for i in range(num):
img = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(4+i*2,4+i*2)).apply(img)
return img
img = cv2.VideoCapture(1)
while(True):
ret, frame = img.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cl3 = multi_clahe(cl1, 5)
cv2.imshow('image', cl3)
k = cv2.waitKey(1) & 0xFF
if k == ord("a")
cv2.imwrite(time.strftime("Screenshot%Y%m%d%H%M%S.jpg"),final)
cv2.imwrite(time.strftime("1.jpg"),cl3)
cv2.imwrite("temp.jpg",cl3)
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
img.release()
cv2.destroyAllWindows()
I need to remove noises from CLAHE in Python.

how to speed up python code from 2.5 to 30 FPS or more in real time video?

I am trying to detect objects in real time video and need to speed up from 2.5 to 30 frames per second (FPS) or more. Unfortunately, it requests 30 FPS at least to work well.
Have any way to speed up it?
Full code:
import cv2
import numpy as np
from imutils.video import FPS
# capturing video through webcam
import time
from skimage.morphology import disk
from skimage.filters.rank import entropy
from skimage.filters import threshold_otsu
cap = cv2.VideoCapture(0)
# video dimension in python-opencv
width = cap.get(3) # float
height = cap.get(4) # float
print width, height
time.sleep(2.0)
fps = FPS().start()
while (1):
_, img = cap.read()
if _ is True:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# img =cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
else:
continue
kernal = np.ones((5, 5))
# entropy_img = entropy(img, disk(10))
entropy_img = entropy(img, kernal)
# print type(entropy_img), entropy_img
thresh = threshold_otsu(entropy_img)
# print thresh
# binary = entropy_img <= thresh
ret1, th1 = cv2.threshold(entropy_img, thresh, 255, cv2.THRESH_BINARY_INV)
# cv2.imshow("img", img)
# cv2.imshow("median", median)
cv2.imshow("threshold", th1)
# cv2.imshow("kernel", g_kernel)
if cv2.waitKey(10) & 0xFF == ord('q'):
cap.release()
cv2.destroyAllWindows()
break
fps.update()
fps.stop()
print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
Note: I have GPU (1050).
Maybe it's because of the size of your image. Skimage entropy is a little expensive.
By this point of view, you have two options:
Lower your image resolution, if it's a possibity
Slice you image in pieces, process each of it in parallel using your video card and then merge it all again.
For the second option, maybe you will have to slice the image in 12~15 pieces.
This might be helpful to make things work in parallel: https://devblogs.nvidia.com/numba-python-cuda-acceleration/
wow you have a powerful gpu. i suggest you to use opencv dnn or cuda to improve the fps

Controlling Contrast and Brightness of Video Stream in OpenCV and Python

I’m using OpenCV3 and Python 3.7 to capture a live video stream from my webcam and I want to control the brightness and contrast. I cannot control the camera settings using OpenCV's cap.set(cv2.CAP_PROP_BRIGHTNESS, float) and cap.set(cv2.CAP_PROP_BRIGHTNESS, int) commands so I want to apply the contrast and brightness after each frame is read. The Numpy array of each captured image is (480, 640, 3). The following code properly displays the video stream without any attempt to change the brightness or contrast.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I get a washed-out video stream when I use Numpy’s clip() method to control the contrast and brightness, even when I set contrast = 1.0 (no change to contrast) and brightness = 0 (no change to brightness). Here is my attempt to control contrast and brightness.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
contrast = 1.0
brightness = 0
frame = np.clip(contrast * frame + brightness, 0, 255)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
How can I control the contrast and brightness of a video stream using OpenCV?
I found the solution using the numpy.clip() method and #fmw42 provided a solution using the cv2.normalize() method. I like the cv2.normalize() solution slightly better because it normalizes the pixel values to 0-255 rather than clip them at 0 or 255. Both solutions are provided here.
The cv2.normalize() solution:
Brightness - shift the alpha and beta values the same amount. Alpha
can be negative and beta can be higher than 255. (If alpha >= 255,
then the picture is white and if beta <= 0, then the picure is black.
Contrast - Widen or shorten the gap between alpha and beta.
Here is the code:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.normalize(frame, frame, 0, 255, cv2.NORM_MINMAX)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
The numpy.clip() solution:
This helped me solve the problem: How to fast change image brightness with python + OpenCV?. I need to:
Convert Red-Green Blue (RGB) to Hue-Saturation-Value (HSV) first
(“Value” is the same as “Brightness”)
“Slice” the Numpy array to the Value portion of the Numpy array and adjust brightness and contrast on that slice
Convert back from HSV to RGB.
Here is the working solution. Vary the contrast and brightness values. numpy.clip() ensures that all the pixel values remain between 0 and 255 in each on the channels (R, G, and B).
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
contrast = 1.25
brightness = 50
frame[:,:,2] = np.clip(contrast * frame[:,:,2] + brightness, 0, 255)
frame = cv2.cvtColor(frame, cv2.COLOR_HSV2BGR)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
import cv2 as cv
cap = cv.VideoCapture(0)
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# normalize the frame
frame = cv.normalize(
frame, None, alpha=0, beta=255, norm_type=cv.NORM_MINMAX, dtype=cv.CV_8UC1
)
# Display the resulting frame
cv.imshow("frame", frame)
# press q to quit
if cv.waitKey(1) & 0xFF == ord("q"):
break

How do I find an image similar to the input image from a directory?

I have a python program which will detect images from webcam. Now, I want to compare the image recognized by the webcam with the images in my directory and check if the exact similar image is already existing or not.
I have tried using this recognition algorithm but it does not work. The program always outputs single image no matter how different the input image is.
The input image(the image scanned by the webcam) is little blurry like this while the image in the data set looks like this
I need an algorithm which can recognize these images with more accuracy.
Here i write a small script for you, hope that it could solve your problem
import cv2
import os
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
def read_img_from_dir(directory, query_shape):
# query_shape is a tuple which contain the size (width, height) of query image
# directory is your dir contain image you wanna find
name_image = []
shape = query
first = True
for pics in os.listdir(directory):
name_image.append(pics)
image = Image.open(pics)
image = image.resize(shape)
image = np.array(image)
image = np.reshape(image,(1,-1))
if first:
img_array = np.copy(image)
first = False
else:
img_array = np.concatenate((img,array,image),axis=0)
return name_image, img_array
def find_by_knn(img, list_name, list_array):
# image_query is path of your picture you wanna find
# list_name and list_array is result of above function
img = np.reshape(img,(1,-1))
num_pics = list_array.shape[0]
dists = np.zeros((num_pics,1))
dists = list(np.sqrt(np.sum((list_array-img)**2,axis = 1)))
idx = dists.index(max(dists))
return list_name[idx]
img = cv2.imread(image_query)
shape = img.shape[:2]
name_image, img_array = read_img_from_dir(directory,shape)
result = find_by_knn(img, name_image, img_array)
print(result)
If you wanna know more about KNN, take a look at this link: http://cs231n.github.io/classification/#nn
IMAGE SEARCH by using python openCV.
LINK FOR open CV
opencv_python‑4.1.0+contrib‑cp35‑cp35m‑win_amd64.whl
download the import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('watch.jpg',cv2.IMREAD_GRAYSCALE)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
pip install numpy
pip install matplotlib
Matplotlib is used for displaying frames from video or images.
Numpy is used for all things "numbers and Python."
We are mainly making use of Numpy's array functionality.
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('watch.jpg',cv2.IMREAD_GRAYSCALE)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Firstly we are going to import few things
Next, we define img to be cv2.read(image file, parms).
The default is going to be IMREAD_COLOR, which is color without any alpha channel.
For the second parameter, you can use -1, 0, or 1. Color is 1, gray scale is 0, and the unchanged is -1. Thus, for gray scale, one could do img = cv2.imread('watch.jpg', 0)
Once loaded, we use cv2.imshow(title,image) to show the image. From here,
we use the cv2.waitKey(0) to wait until any key is pressed. Once that's done,
we use cv2.destroyAllWindows() to close everything.
Loading Video Source Open CV Python
with video and webcams.
handling frames from a video is identical to handling for images.
code--
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
we import numpy and cv2 Next, we cay cap = cv2.VideoCapture(0).
while(True):
ret, frame = cap.read()
we have ret and frame being defined as the cap.read().
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
*we define a new variable, gray, as the frame, converted to gray.
note**
*OpenCV reads colors as BGR (Blue Green Red),
where most computer applications read as RGB (Red Green Blue).
cv2.imshow('frame',gray)
Here, we're showing the converted-to-gray feed.
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if key is a q, we will exit the while loop with a break, which then runs:
cap.release()
cv2.destroyAllWindows()
This releases the webcam, then closes all of the imshow() windows.
if you want to save the recording and then process it by using,
import numpy as np
import cv2
cap = cv2.VideoCapture(1)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out.write(frame)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()

In OpenCV I've got a mask of an area of a frame. How would I then insert another image into that location on the original frame?

I'm brand new to OpenCV and I can't seem to find a way to do this (It probably has to do with me not knowing any of the specific lingo).
I'm looping through the frames of a video and pulling out a mask from the video where it is green-screened using inRange. I'm looking for a way to then insert an image into that location on the original frame. The code i'm using to pull the frames/mask is below.
import numpy as np
import cv2
cap = cv2.VideoCapture('vid.mov')
image = cv2.imread('photo.jpg')
# green digitally added not much variance
lower = np.array([0, 250, 0])
upper = np.array([10, 260, 10])
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame', frame)
# get mask of green area
mask = cv2.inRange(frame, lower, upper)
cv2.imshow('mask', mask)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Use Bitwise operations for masking and related binary operations. Please check below code to see how Bitwise operations are done.
Code
import numpy as np
import cv2
cap = cv2.VideoCapture('../video.mp4')
image = cv2.imread('photo.jpg')
# green digitally added not much variance
lower = np.array([0, 250, 0])
upper = np.array([10, 260, 10])
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame', frame)
# get mask of green area
mask = cv2.inRange(frame, lower, upper)
notMask = cv2.bitwise_not(mask)
imagePart=cv2.bitwise_and(image, image, mask = mask)
videoPart=cv2.bitwise_and(frame, frame, mask = notMask)
output = cv2.bitwise_or(imagePart, videoPart)
cv2.imshow('output', output)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
RGB bad color space
Since, you are doing color processing, I would suggest you to use appropriate color space. HSV would be a good start for you. For finding good range of HSV values, try this script.
Generating Video Output
You need a to create a video writer and once all image processing is done, write the processed frame to a new video. I am pretty sure, you cannot read and write to same video file.
Further see official docs here.
It has both examples of how to read and write video.

Categories

Resources