UpperBody detection using haar cascade - computer-vision

I'm trying to detect the upper body using haar cascade.
But still I'm not getting any detection on the image.
import numpy as np
import cv2
cascade = cv2.CascadeClassifier('haarcascade_upperbody.xml');
imgPath = '/home/ayush/Desktop/images.jpeg';
img = cv2.imread(imgPath);
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
body = cascade.detectMultiScale(
gray,
scaleFactor = 1.1,
minNeighbors = 5,
minSize = (30,30),
flags = cv2.CASCADE_SCALE_IMAGE
)
for (x, y, w, h) in body:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('Upper Body',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Why is it so?
I'm using OpenCV3.

It is possible that your scaleFactor is too small. I tried running your code exactly (though with my own image) and found no results at 1.1, but found results at 1.01.
See here for a description of how the parameter affects your results.

That's because the file haarcascade_upperbody.xml is trained to be used with pedestrian detection, and very probably your image is not matching to this case.

Related

OpenCV - Highlight mouth region after detection

I want to extract only the rectangular part of the mouth detected by my code how can I do it:
import numpy as np
import cv2
face_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml')
mouth_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_smile.xml')
img = cv2.imread('Images/image_0033.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
mouth = mouth_cascade.detectMultiScale(roi_gray,2.0,25)
for (ex,ey,ew,eh) in mouth:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),3)
cv2.imshow('img',nwimg)
cv2.waitKey(0)
cv2.destroyAllWindows()
As seen in the code I just want to extract the rectangular mouth region I have used commands like var = img[y:y+h,x:x+w] but this has not worked.
It is simple, replace this line:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),3) with
cv2.rectangle(img,(ex,ey),(ex+ew,ey+eh),(0,255,0),3)
and display the following:
cv2.imshow('Detected Mouth',img)
In this way you will draw a rectangle over the mouth.
EDIT
You can crop your region of interest (in this case the mouth) using numpy operation as follows:
crop_img = img[ey:ey+eh, ex:ex+ew]
cv2.imshow('Cropped Mouth',crop_img)
This is what I got:
Sample 1:
Sample 2:

Fingerprint enhancement

Fingerprint sensor (Persona) is being used to get a fingerprint image. I am trying to enhance this image. I am using OpenCV for this purpose. Here is my original image:
I have applied otsu transform on it and got this image:
Now I have applied Gabor filter from OpenCV on orientations of 0, 45, 90, 135. I have got this result:
Here is my code in Python OpenCV for application of gabor filter:
import numpy as np
import cv2
from matplotlib import pyplot as plt
//cv2.getGaborKernel(ksize, sigma, theta, lambda, gamma, psi, ktype)
// ksize - size of gabor filter (n, n)
// sigma - standard deviation of the gaussian function
// theta - orientation of the normal to the parallel stripes
// lambda - wavelength of the sunusoidal factor
// gamma - spatial aspect ratio
// psi - phase offset
// ktype - type and range of values that each pixel in the gabor kernel
//canhold
g_kernel = cv2.getGaborKernel((25, 25), 6.0, np.pi/4, 8.0, 0.5, 0, ktype=cv2.CV_32F)
g_kernel1 = cv2.getGaborKernel((30, 30), 6.0, (3*np.pi)/4, 8.0, 0.5, 0, ktype=cv2.CV_32F)
g_kernel2 = cv2.getGaborKernel((30, 30),4 , 0, 8, 0.5, 0, ktype=cv2.CV_32F)
g_kernel3 = cv2.getGaborKernel((30, 30),4 , np.pi, 8, 0.5, 0, ktype=cv2.CV_32F)
print np.pi/4
img = cv2.imread('C:/Users/admin123/Desktop/p.png')
img1 = cv2.imread('C:/Users/admin123/Desktop/p.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
// Otsu thresholding
ret2,img1 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow('otsu', img1)
filtered_img = cv2.filter2D(img, cv2.CV_8UC3, g_kernel)
filtered_img1 = cv2.filter2D(img, cv2.CV_8UC3, g_kernel1)
filtered_img2 = cv2.filter2D(img, cv2.CV_8UC3, g_kernel2)
filtered_img3 = cv2.filter2D(img, cv2.CV_8UC3, g_kernel3)
cv2.imshow('0', filtered_img)
cv2.imshow('1', filtered_img1)
cv2.imshow('2', filtered_img2)
cv2.imshow('image', img)
cv2.addWeighted(filtered_img2,0.4,filtered_img1,0.8,0,img) #0 degree and 90
cv2.addWeighted(img,0.4,filtered_img,0.6,0,img) #0 degree and 90
cv2.addWeighted(img,0.4,filtered_img3,0.6,0,img)
cv2.addWeighted(img,0.4,img1,0.6,0.3,img)
cv2.imshow('per',img)
//threshold will convert it plain zero and white image
ret,thresh1 = cv2.threshold(img,150,255,cv2.THRESH_BINARY)#127 instead of 200
cv2.imshow('per1',thresh1)
h, w = g_kernel.shape[:2]
g_kernel = cv2.resize(g_kernel, (3*w, 3*h), interpolation=cv2.INTER_CUBIC)
g_kernel1 = cv2.resize(g_kernel1, (3*w, 3*h), interpolation=cv2.INTER_CUBIC)
cv2.imshow('gabor kernel (resized)', g_kernel)
cv2.imshow('gabor kernel1 (resized)', g_kernel1)
cv2.waitKey(0)
cv2.destroyAllWindows()
I want robust fingerprint recognition. For this I want image of this level to get accurate Minutiae points:
How can I get this much result from enhancement? What changes are required in code to get the enhanced result?
Well I dont have a python/opencv answer but I can point you the resource where you can fiddle around with a Matlab code. You can find the code here Simple Fingerprint Matcher
The code basically holds all the code for enhacement/minutiae extraction/matching. Though not very robust on matching but enhancements are pretty good.
I ran the code on the sample you uploaded, which came out as follows.
Note that the code uses two different approaches combined for fingerprint enhancement. One is based on Gabor filters and the other is called STFT (Short Time Fourier Transform), But it is likely that you will only need the Gabor filter part. Actually depends upon the image quality.
If you need the Gabor filter code in Matlab, you can find it herehttp://www.peterkovesi.com/matlabfns/#fingerprints
But I did modify the code to show up the images and process only a single finger.
The following is the main file calling in steps the extraction of enhanced fingerprint. The matlab function doing that is f_enhance.m
function [ binim, mask, cimg1, cimg2, oimg1, oimg2 ] = f_enhance( img )
enhimg = fft_enhance_cubs(img,6); % Enhance with Blocks 6x6
enhimg = fft_enhance_cubs(enhimg,12); % Enhance with Blocks 12x12
[enhimg,cimg2] = fft_enhance_cubs(enhimg,24); % Enhance with Blocks 24x24
blksze = 5; thresh = 0.085;
normim = ridgesegment(enhimg, blksze, thresh);
oimg1 = ridgeorient(normim, 1, 3, 3);
[enhimg,cimg1] = fft_enhance_cubs(img, -1);
[normim, mask] = ridgesegment(enhimg, blksze, thresh);
oimg2 = ridgeorient(normim, 1, 3, 3);
[freq, medfreq] = ridgefreq(normim, mask, oimg2, 32, 5, 5, 15);
binim = ridgefilter(normim, oimg2, medfreq.*mask, 0.5, 0.5, 1);
figure,imshow(binim,[]); % Normalize to grayscale
binim = ridgefilter(normim, oimg2, medfreq.*mask, 0.5, 0.5, 1) > 0;
figure;
figure,imshow(binim);
figure;
end
Either you revert to Matlab or you can always translate the code :)
Good luck
I may be late here. But this might be useful for other people later on.
Take a look at this reporitory:
https://github.com/Utkarsh-Deshmukh/Fingerprint-Enhancement-Python
It performs Fingerprint Enhancement using oriented Gabor filters in python.
installation:
pip install fingerprint_enhancer
usage:
import fingerprint_enhancer # Load the library
img = cv2.imread('image_path', 0) # read input image
out = fingerprint_enhancer.enhance_Fingerprint(img) # enhance the fingerprint image
cv2.imshow('enhanced_image', out); # display the result
cv2.waitKey(0)

Face detection and roi cropping using opencv python

I took the code from this post:
how to crop the detected face in opencv and save roi as image in opencv python
The problem is that when I run this code, it shows a grey screen instead of showing the video from webcam.
Here's my coding:
import cv2
import os, sys
TRAINSET = "haarcascade_frontalface_default.xml"
DOWNSCALE = 4
cam = cv2.VideoCapture(0) #capture a video
cv2.namedWindow("preview")
classifier = cv2.CascadeClassifier(TRAINSET)
Compare_images=[]
for file in os.listdir("D:/Python code"):
if file.endswith(".jpg"):
Compare_images.append(file)
while True: # try to get the first frame
_, frame = cam.read()
key = cv2.waitKey(20)
if(key==32):
print "Name of Image:"
n= raw_input()
value=len(Compare_images)
cv2.imwrite('images/image'+str(n)+'.jpg', frame)
saved_image=cv2.imread("images/image"+str(n)+".jpg")
minisize = (saved_image.shape[1]/DOWNSCALE,saved_image.shape[0]/DOWNSCALE)
miniframe = cv2.resize(saved_image, minisize)
faces = classifier.detectMultiScale(miniframe)
for f in faces:
x, y, w, h = [ v*DOWNSCALE for v in f ]
print x
print y,w,h
x0,y0=int(x),int(y)
x1,y1=int(x+w),int(y+h)
print x0,y0,y1,y0
image = cv2.rectangle(saved_image, (x0,y0), (x1,y1), (0,0,255),2)
roi=saved_image[y0:y1,x0:x1]#crop
cv2.imwrite('roi.jpg',roi)
cv2.imshow("adsa", saved_image)
cv2.putText(frame, "Press ESC to close.", (5, 25), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,255))
cv2.imshow("preview", frame)
I'm really new into python, and I would really appreciate it if you are able to help!

CascadeClassifier in OpenCV generates error

I am trying to develop a simple application to detect faces as well as eyes in a given image:
from cv2 import *
face_cascade = CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = CascadeClassifier('haarcascade_eye.xml')
img = imread("123.jpg")
gray = cvtColor(img, COLOR_BGR2GRAY)
rows,cols = gray.shape
gray = getRotationMatrix2D((cols/2,rows/2),-90,1)
faces = face_cascade.detectMultiScale(gray, 1.3, 5, 0)
print faces
for (x,y,w,h) in faces:
img = rectangle(img, (x,y), ((x+w),(x+h)), (255,0,0), 2)
#gray = rectangle(gray, (x,y), ((x+w), (x+y)), (0, 255, 0), 4)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_grey)
for (ex,ey, ew, eh) in eyes:
roi_color = rectangle(roi_color, (x,y), ((x+w), (y+h)), (50, 50, 50), 3)
imshow("img", img)
waitKey(9)
destroyAllWindows()
(Note: The rotation is necessary, as after using the cvtColor function, the output image is generated with a rotation of 90 degrees counter clockwise.)
I am getting the following error:
Traceback (most recent call last): File "/home/namit/Codes/wow.py",
line 10, in faces = face_cascade.detectMultiScale(gray, 1.3,
5, 0) error:
/home/namit/OpenCV/opencv-2.4.9/modules/objdetect/src/cascadedetect.cpp:1081:
error: (-215) scaleFactor > 1 && image.depth() == CV_8U in function
detectMultiScale
The cause of the error message was that the image gray was float64 while face_cascade.detectMultiScale requires unisigned integer. The fix for that is to convert the image to uint8 before calling `face_cascade.detectMultiScale``:
import numpy as np
gray = np.array(gray, dtype='uint8')
There were other issues. For one, cv2.rectangle does not return an image; instead it modifies the image that you pass to it. The following works for me:
from cv2 import *
import numpy as np
face_cascade = CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = CascadeClassifier('haarcascade_eye.xml')
fname='123.jpg'
img = imread(fname)
gray = imread(fname, CV_LOAD_IMAGE_GRAYSCALE)
rows,cols = gray.shape
gray = np.array(gray, dtype='uint8')
faces = face_cascade.detectMultiScale(gray, 1.3, 5, 0)
print 'faces=', faces
for (x,y,w,h) in faces:
rectangle(img, (x,y), ((x+w),(x+h)), (255,0,0), 2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey, ew, eh) in eyes:
rectangle(roi_color, (x,y), ((x+w), (y+h)), (50, 50, 50), 3)
imshow('eyes=%s' % (eyes,), roi_color)
imshow("img", img)
waitKey(0)
destroyAllWindows()
I did not observe a problem with image rotation, so I removed the rotation code.

OpenCV warping image based on calcOpticalFlowFarneback

I'm trying to perform a complex warp of an image using Dense Optical Flow. I am trying to warp the second image into roughly the same shape as the first image.
cv::Mat flow;
cv::calcOpticalFlowFarneback( mGrayFrame1, mGrayFrame2, flow, 0.5, 3, 15, 3, 5, 1.2, 0 );
cv::Mat newFrame = cv::Mat::zeros( frame.rows, frame.cols, frame.type() );
cv:remap( frame, newFrame, flow, cv::Mat(), CV_INTER_LINEAR );
I calculate the flow from two grayscale frames. I am now trying to remap my original (i.e. non-grayscale) image using this flow information using the cv::remap function. However, I get a very badly distorted image from it. I simply end up with an orange and black image that bears a small resemblance to my original image.
How do I use cv::remap with the calculated flow?
The remap function cannot work with flow directly. One must use a separate map that is computed by taking the backwards flow (from frame2 to frame1) and then offsetting each flow vector by its (x, y) location on the pixel grid. See details below.
Recall the backwards optical flow formula:
frame1(x, y) = frame2(x + flowx(x, y), y + flowy(x, y))
The remap function transforms the source image using a specified map:
dst(x, y) = src(mapx(x, y), mapy(x, y))
Comparing the two equations above, we may determine the map that remap requires:
mapx(x, y) = x + flowx(x, y)
mapy(x, y) = y + flowy(x, y)
Example:
Mat flow; // backward flow
calcOpticalFlowFarneback(nextFrame, prevFrame, flow);
Mat map(flow.size(), CV_32FC2);
for (int y = 0; y < map.rows; ++y)
{
for (int x = 0; x < map.cols; ++x)
{
Point2f f = flow.at<Point2f>(y, x);
map.at<Point2f>(y, x) = Point2f(x + f.x, y + f.y);
}
}
Mat newFrame;
remap(prevFrame, newFrame, map);
Here is a Python solution to warp image from optical flow:
import cv2
import numpy as np
def warp_flow(flow, img1=None, img2=None, interpolation=cv2.INTER_LINEAR):
"""Use remap to warp flow, generating a new image.
If img1 is input, the output will be img2_warped, but there will be multiple pixels corresponding to a single pixel, resulting in sparse holes.
If img2 is input, the output will be img1_warped, and there will be no sparse holes. The latter approach is preferred.
Args:
flow (np.ndarray): flow
img1 (np.ndarray, optional): previous frame
img2 (np.ndarray, optional): next frame
Returns:
warped image"
"""
h, w, _ = flow.shape
remap_flow = flow.transpose(2, 0, 1)
remap_xy = np.float32(np.mgrid[:h, :w][::-1])
if img1 is not None:
uv_new = (remap_xy + remap_flow).round().astype(np.int32)
mask = (uv_new[0] >= 0) & (uv_new[1] >= 0) & (uv_new[0] < w) & (uv_new[1] < h)
uv_new_ = uv_new[:, mask]
remap_xy[:, uv_new_[1], uv_new_[0]] = remap_xy[:, mask]
remap_x, remap_y = remap_xy
img2_warped = cv2.remap(img1, remap_x, remap_y, interpolation)
mask_remaped = np.zeros((h, w), np.bool8)
mask_remaped[uv_new_[1], uv_new_[0]] = True
img2_warped[~mask_remaped] = 0
return img2_warped
elif img2 is not None:
remap_x, remap_y = np.float32(remap_xy + remap_flow)
return cv2.remap(img2, remap_x, remap_y, interpolation)
img1 = cv2.imread("img1.jpg")
img2 = cv2.imread("img2.jpg")
flow = cv2.calcOpticalFlowFarneback(
img1.mean(-1), img2.mean(-1), None, 0.5, 3, 15, 3, 5, 1.2, 0
)
img2_warped = warp_flow(flow, img1=img1)
img1_warped = warp_flow(flow, img2=img2)
cv2.imwrite("warped.jpg", np.vstack([img1_warped, img2_warped]))
cv2.imwrite("target.jpg", np.vstack([img1, img2]))
The examples img1 img2 and flow visualization :
The results warped.jpg target.jpg: