How to fetch the closest image in OpenCV - python

I've used the below code. However, I'm able to take control of the faces in the webcam. However, how to fetch the closest image to the camera. Can anyone help ?
import cv2
import numpy as np
import time
face_cascade = cv2.CascadeClassifier('C:\\Users\\Admin\\Desktop\\opencv\\opencv\\data\\haarcascades\\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('C:\\Users\\Admin\\Desktop\\opencv\\opencv\\data\\haarcascades\\haarcascade_eye.xml')
cap = cv2.VideoCapture(0)
while True:
ret,img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3,5)
print len(faces)
for(x,y,w,h) in faces:
crop_img = img[y: y + h, x: x + w] #Crop from x, y, w, h->100, 200, 300, 400
ts = time.time()
'cv2.imwrite("C:\\Users\\Admin\\Desktop\\opencv\\detectedfaces\\"+str(ts)+".jpg", crop_img)'
cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
roi_gray = gray[y:y+h,x:x+h]
roi_color = img[y:y+h,x:x+h]
eyes = eye_cascade.detectMultiScale(roi_gray)
for(ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color, (ex,ey), (ex+ew,ey+eh), (0,255,0), 2)
cv2.imshow('img',img)
time.sleep(5)
k = cv2.waitKey(1) & 0xFF == ord('q')
if k == 27:
break;
cap.release()
cv2.destroAllWindows()

Since you have the eye locations, I'd just use IOD (inter-ocular distance). Basically the distance between the center of your two eye ROIs. That metric could be used to infer distance from the camera.
Something like this will do the job:
if len(eyes) >= 2:
IOD = abs((eyes[0][0] + eyes[0][1] / 2.0) - (eyes[1][0] + eyes[1][1] / 2.0))
cv2.putText(img,'%d'%IOD, (30,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 1)
It won't be terribly accurate if two people are at roughly the same distance from the camera, but I don't think much will. You could also correlate facial width and IOD to compensate for people with different sized heads.

Related

detect moving object with opencv and python

i found very interesting article about detection of moving objects, here is correspondng link :Detection of moving object
and also corresponding article : Article about object detection
i followed code and try to implement my self, here is corresponding code :
import cv2
import numpy as np
import matplotlib.pyplot as plt
from Background_Image_Creation import get_background
cap =cv2.VideoCapture("video_1.mp4")
#print(cap.get(cv2.CAP_PROP_FRAME_COUNT))
#print(cap.get(cv2.CAP_PROP_FPS))
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
save_name = "Result.mp4"
# define codec and create VideoWriter object
out = cv2.VideoWriter(save_name,cv2.VideoWriter_fourcc(*'mp4v'), 10, (frame_width, frame_height))
background_frame =get_background("video_1.mp4")
background = cv2.cvtColor(background_frame, cv2.COLOR_BGR2GRAY)
print(background.shape)
frame_count =0
consecutive_frame=8
#frame_diff_list =[]
while cap.isOpened():
ret,frame =cap.read()
print(ret)
print(frame.shape)
if ret==True:
frame_count+=1
orig_frame =frame.copy()
gray =cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
if frame_count % consecutive_frame == 0 or frame_count == 1:
frame_diff_list =[]
frame_diff = cv2.absdiff(gray, background)
ret, thresh = cv2.threshold(frame_diff, 50, 255, cv2.THRESH_BINARY)
dilate_frame = cv2.dilate(thresh, None, iterations=2)
frame_diff_list.append(dilate_frame)
print(frame_diff_list)
if len(frame_diff_list) == consecutive_frame:
# add all the frames in the `frame_diff_list`
sum_frames = sum(frame_diff_list)
print(sum_frames)
# find the contours around the white segmented areas
contours, hierarchy = cv2.findContours(sum_frames, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw the contours, not strictly necessary
for i, cnt in enumerate(contours):
cv2.drawContours(frame, contours, i, (0, 0, 255), 3)
for contour in contours:
# continue through the loop if contour area is less than 500...
# ... helps in removing noise detection
if cv2.contourArea(contour) < 500:
continue
# get the xmin, ymin, width, and height coordinates from the contours
(x, y, w, h) = cv2.boundingRect(contour)
# draw the bounding boxes
cv2.rectangle(orig_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('Detected Objects', orig_frame)
out.write(orig_frame)
if cv2.waitKey(100) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
code for background frame creation is also presented :
import numpy as np
import cv2
import matplotlib.pyplot as plt
def get_background(path):
cap =cv2.VideoCapture(path)
frame_indices =cap.get(cv2.CAP_PROP_FRAME_COUNT)*np.random.uniform(size=50)
frames =[]
for idx in frame_indices:
cap.set(cv2.CAP_PROP_POS_FRAMES,idx)
ret,frame =cap.read()
frames.append(frame)
median_frame = np.median(frames, axis=0).astype(np.uint8)
return median_frame
#median_frame =get_background("video_1.mp4")
#cv2.imshow("Median_Background",median_frame)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
#plt.show()
code runs fine, but output video does not contain anything, it just 1 KGB size, one thing what i am thinking is that this fragment
frame_diff_list.append(dilate_frame)
is colored with yellow color, here is screenshot :
and also when i try to print print(frame_diff_list)
it just printed one output :
i was more surprised when i have tested
print(ret)
print(frame.shape)
from the begining of the loop and it just printed one output :
True
(360, 640, 3)
it seems that loop does not cover all frames right? could you help me please to figure out what is wrong with my code?

How can I detect circle by using openCV in python?

I want to detect circle in a picture by using haar cascade. I created an cascade xml.
import cv2
import numpy as np
img = cv2.imread("C://OpenCVcascade//resimler//coins.jpg")
circles_cascade = cv2.CascadeClassifier("C://Cascade//dairetanima.xml")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
circles = circles_cascade.detectMultiScale(gray, 1.1, 1)
if circles is not None:
circles = np.uint16(np.around(circles))
for (x, y, w, h) in circles:
center = (x + w // 2, y + h // 2)
radius = (w + h) // 4
cv2.circle(img, center, radius, (255, 0, 0), 2)
cv2.imshow('image', img)
cv2.waitKey()
cv2.destroyAllWindows()
My result:
I already know, there are different method to detect circle. But I am trying to do with cascade method. Because after this part, I will use it for real time detection.

Can we use Haar Classifier to detect Iris of an eye as done for face and eyes?

I am currently trying to detect iris and subsequently pupil within a given image. All approaches seen online, detect the face, then the eyes and then use thresholding, hough transformation, and contouring to finally detect the pupil.
If we already have a large data set of pupils, can't we train a Haar Classifier as done in the case of Face and Eyes to detect iris of an eye? Is there any reason this shouldn't work?
Currently, I have a partially working solution using the non-haar based approach.
Example of one working code that
import math
import cv2
eye_cascade = cv2.CascadeClassifier('./cascade_files/haarcascade_eye.xml')
if eye_cascade.empty():
raise IOError('Unable to load the eye cascade classifier xml file')
cap = cv2.VideoCapture(0)
ds_factor = 0.5
ret, frame = cap.read()
contours = []
while True:
ret, frame = cap.read()
frame = cv2.resize(frame, None, fx=ds_factor, fy=ds_factor, interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
eyes = eye_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=1)
for (x_eye, y_eye, w_eye, h_eye) in eyes:
pupil_frame = gray[y_eye:y_eye + h_eye, x_eye:x_eye + w_eye]
ret, thresh = cv2.threshold(pupil_frame, 80, 255, cv2.THRESH_BINARY)
cv2.imshow("threshold", thresh)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
for contour in contours:
area = cv2.contourArea(contour)
rect = cv2.boundingRect(contour)
x, y, w, h = rect
radius = 0.15 * (w + h)
area_condition = (100 <= area <= 200)
symmetry_condition = (abs(1 - float(w)/float(h)) <= 0.2)
fill_condition = (abs(1 - (area / (math.pi * math.pow(radius, 2.0)))) <= 0.4)
cv2.circle(frame, (int(x_eye + x + radius), int(y_eye + y + radius)), int(1.3 * radius), (0, 180, 0), -1)
cv2.imshow('Pupil Detector', frame)
c = cv2.waitKey(1)
if c == 27:
break
cap.release()
cv2.destroyAllWindows()
Example output:
Yes, you could train a pupil detector directly with sample images on a Haar Cascade classifier. If you aren't constrained to small hardware at high throughput, then I would recommend using deep learning to train on the same dataset, you could expect better results.

How to give numbers to the rectangles that i drew for counting people?

I used mixture of gaussians algorithm than i used tresholding to clear shadows.Then I used contours to find white objects. Then i drew rectangles around them. Now I want to give numbers to these rectangles and i want numbers to track rectangles for counting people.
Here is the code i used if you can give me some idea about counting it would be awesome.
import numpy as np
import cv2
import sys
video_path = 'video.avi'
cv2.ocl.setUseOpenCL(False)
version = cv2.__version__.split('.')[0]
print(version)
cap = cv2.VideoCapture(video_path)
if version == '2' :
fgbg = cv2.BackgroundSubtractorMOG2()
if version == '3':
fgbg = cv2.createBackgroundSubtractorMOG2()
while (cap.isOpened):
ret, frame = cap.read()
if ret==True:
fgmask = fgbg.apply(frame)
ret1,th1 = cv2.threshold (fgmask,150,200,cv2.THRESH_BINARY)
if version == '2' :
(contours, hierarchy) = cv2.findContours(th1.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
if version == '3' :
(im2, contours, hierarchy) = cv2.findContours(th1.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) < 500:
continue
(x, y, w, h) = cv2.boundingRect(c) cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('foreground and background',th1)
cv2.imshow('rgb',frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()

how to identify the position of detected face

I have to detect faces using openCV and python. Then identify the position of the detected face if it is in the right, the left or the middle of the screen.
I already succeed to detect faces using the code below and still to know the position of the faces could someone please help me ?
import cv2
import sys
import numpy as np
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(1)
while True:
#capture frame by frame
ret,frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,
scaleFactor=1.1,
minNeighbors= 5,
minSize=(30, 30),
flags=cv2.cv.CV_HAAR_SCALE_IMAGE)
#Draw a rectangle around the faces
for (x, y, w,h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255, 0), 2)
cv2.imshow('video',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
You could get the centre of the rectangle:
centre_x = x + w/2
centre_y = y + y/2
Then compare it with the size of the image. Assuming you have the image shape information:
height, width, channels = frame.shape #it could be gray.shape too
You can understand for example if the face is detected on the left side of the image by checking centre_x<width.
You have all the information to divide the image into a grid and understand where the rectangle places itself.

Categories

Resources