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:
Related
I'm having trouble with reading number from document using Tesseract OCR.
I have cut text from the document. And using Tesseract OCR to read it. But nothing print in the command line.
I have test it with simple document white background and black number. It work perfect.
This is my code to detect number:
orc->SetImage(source.data, source.size().width, source.size().height, source.channels(),
source.step1());
QString outText = QString::fromUtf8(orc->GetUTF8Text());
if (outText != "")
qDebug() << outText;
And this is my picture:
Can someone tell me where i'm wrong ?
I do not know how to do it in c++. But I can get the numbers using this code in python. I think the key is processing in hsv color mode.
import cv2
import numpy as np
import pytesseract
img = cv2.imread("djwtV.png", cv2.IMREAD_COLOR)
img = cv2.resize(img, None, fx=3, fy=3)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
upper = np.array([255, 255, 150])
lower = np.array([0, 0, 0])
mask = cv2.inRange(hsv, lower, upper)
mask = cv2.bitwise_not(mask)
custom_config = r'-l eng --oem 3 --psm 6 -c tessedit_char_whitelist="0123456789,"'
text = pytesseract.image_to_string(mask, config=custom_config)
print("Detected: ", text)
cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
The result
Detected: 4,691,613
And if you change the code into this
upper = np.array([255, 255, 125])
custom_config = r'-l jpn --oem 3 --psm 6 '
You will get this
Detected: | 預り金 計①(a+b+c) | 4.691.613
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.
Apologies in advance as i am newbie to OpenCV-Python. I set myself a task to create a Passport type image from the video capture.
Using a head and shoulders Haar Cascade i was able to create a portrait photo but i now want to turn the background to a white background (leaving the head and shoulders portrait in the foreground).
Just not sure how/ best way to do this. Any help would be welcome.
Many thanks in advance.
Here is the code:
import numpy as np
import cv2
# face file
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# eye file
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
# head shoulders file
hs_cascade = cv2.CascadeClassifier('HS.xml')
cap = cv2.VideoCapture(1)
while 1:
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
headshoulders = hs_cascade.detectMultiScale(gray, 1.3, 3)
# find the head and shoulders
for (x,y,w,h) in headshoulders:
# variable change to make portrait orientation
x = int(x*1.5)
w = int(w/1.5)
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# crop the image
crop_img = img[y: y + h, x: x + w]
# show original and crop
cv2.imshow('crop', crop_img)
cv2.imshow('img', img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
elif k == ord('s'):
# save out the portrait image
cv2.imwrite('cropimage.png',crop_img)
# release the camera
cap.release()
cv2.destroyAllWindows()
I got it to work. Here is my solution.
PLEASE NOTE: This worked for HI-RES images (Nikon D7100 - JPEG). LOW-RES did NOT work when i tried a Webcam (Logitech C615).
I used some of the code from a link that was suggested.
# import numpy
import numpy as np
# import cv2
import cv2
# import Matplitlib
from matplotlib import pyplot as plt
# Fill any holes function
def get_holes(image, thresh):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
im_bw = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY)[1]
im_bw_inv = cv2.bitwise_not(im_bw)
im_bw_inv, contour, _ = cv2.findContours(im_bw_inv, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contour:
cv2.drawContours(im_bw_inv, [cnt], 0, 255, -1)
nt = cv2.bitwise_not(im_bw)
im_bw_inv = cv2.bitwise_or(im_bw_inv, nt)
return im_bw_inv
# Remove background Function
def remove_background(image, thresh, scale_factor=.25, kernel_range=range(1, 15), border=None):
border = border or kernel_range[-1]
holes = get_holes(image, thresh)
small = cv2.resize(holes, None, fx=scale_factor, fy=scale_factor)
bordered = cv2.copyMakeBorder(small, border, border, border, border, cv2.BORDER_CONSTANT)
for i in kernel_range:
#kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2*i+1, 2*i+1))
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (2*i+1, 2*i+1))
bordered = cv2.morphologyEx(bordered, cv2.MORPH_CLOSE, kernel)
unbordered = bordered[border: -border, border: -border]
mask = cv2.resize(unbordered, (image.shape[1], image.shape[0]))
fg = cv2.bitwise_and(image, image, mask=mask)
return fg
# Load a color image in grayscale
img = cv2.imread('original/11.png')
# Start background removal -- Parameters are <image> and <threshold level>
nb_img = remove_background(img, 180)
# Change Black Pixels to WHITE
nb_img[np.where((nb_img==[0,0,0]).all(axis=2))] = [255,255,255]
# resize the viewing size (as the images are too big for the screen
small = cv2.resize(nb_img, (300, 400))
# Show the finished image
cv2.imshow('image',small)
k = cv2.waitKey(0) & 0xFF
if k == 27: #wait for ESC key to exit
# if ESC pressed close the camera windows
cv2.destroyAllWindows()
elif k == ord('s'): #wait for 's' key to save and exit
# Save the img(greyscale version)
cv2.imwrite('bg_removal/11.png',small)
cv2.destroyAllWindows()
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!
I'm using the following code to detect certain shapes in an image:
import cv2
import numpy as np
img = cv2.imread("006.jpg")
grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(grey,127,255,1)
cv2.imshow('img',thresh)
cv2.waitKey(0)
contours, h = cv2.findContours(thresh, 1, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key = len)
for contour in contours:
approx = cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour, True), True)
#star - > yellow
if len(approx) == 10:
cv2.drawContours(img, [contour],0, (0,255,255), -1)
#circle -> black
elif len(approx) >= 11:
cv2.drawContours(img, [contour], 0, (0,0,0), -1)
#triangle -> green
elif len(approx) == 3:
cv2.drawContours(img,[contour],0,(0,255,0),-1)
#square -> blue
elif len(approx) == 4:
cv2.drawContours(img, [contour],0, (255,0,0),-1)
#pentagon -> red
elif len(approx) == 5:
cv2.drawContours(img, [contour],0, (0,0,255), -1)
cv2.imshow('img',img)
cv2.waitKey(0)
This code works well for images on my computer, but when i print out the image, take a picture off it
and try to run the code on it again (as here: image) it doesn't work as well as it should.
I already tried using blurs and canny but I'm not able to smoothen my second picture enough.
I hope someone can help!
Probably using fixed threshold value (127 in your case) it is not a good idea in case of photos taken by a camera (although it works in the abstract case, when the shapes are pure color not influenced by a shade). It seems the 127 is too high value for the image you have provided.
Why don't you try with an Otsu method ? Here's an example of how to use with python in opencv. It will make an threshold level invariant to a real environment you get in case of image taken by a camera.