I'm using the code below (which is a googling result) to detect faces:
import io
import picamera
import cv2
import numpy
import PIL
from PIL import Image
from resizeimage import resizeimage
#Load a cascade file for detecting faces
face_cascade = cv2.CascadeClassifier('/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml')
#Create a memory stream so photos doesn't need to be saved in a file
stream = io.BytesIO()
#Get the picture (low resolution, so it should be quite fast)
#Here you can also specify other parameters (e.g.:rotate the image)
with picamera.PiCamera() as camera:
camera.resolution = (640, 480)
camera.vflip = False
camera.hflip = False
camera.brightness = 60
camera.capture(stream, format='jpeg')
#Convert the picture into a numpy array
buff = numpy.fromstring(stream.getvalue(), dtype=numpy.uint8)
#Now creates an OpenCV image
image = cv2.imdecode(buff, 1)
#Load a cascade file for detecting faces
#face_cascade = cv2.CascadeClassifier('/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml')
#Convert to grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#Look for faces in the image using the loaded cascade file
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
print "Found "+str(len(faces))+" face(s)"
#Draw a rectangle around every found face
#Crop faces and save to separate files
id = 1
for (x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
cropped = image[ y : y+h, x : x+w ]
#RESIZE IMAGE to 92x112
cropped = cv2.resize(cropped,None,92,112)
cv2.imwrite("../reco/test_faces/cropped_face" + str(id) + ".png", cropped)
id = id + 1
At the end I want to crop the faces into image files and resize them to 92x112. This is what I try with:
cropped = cv2.resize(cropped,None,92,112)
When I run this I get:
OpenCV Error: Assertion failed (dsize.area() || (inv_scale_x > 0 && inv_scale_y > 0)) in resize, file /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/imgproc/src/imgwarp.cpp, line 1835
Traceback (most recent call last):
File "1track.py", line 48, in <module>
cropped = cv2.resize(cropped,None,92,112)
cv2.error: /build/opencv-ISmtkH/opencv-2.4.9.1+dfsg/modules/imgproc/src/imgwarp.cpp:1835: error: (-215) dsize.area() || (inv_scale_x > 0 && inv_scale_y > 0) in function resize
To resize the image to new dimensions, you need to know the ratio between the new dimensions and the current ones. So if you want to set (for example) a 640x480 image into a 92x112 image:
92/640=0.143
112/480=0.233
You use these ratios in the cv2.resize function:
cropped = cv2.resize(cropped, (0,0), fx=0.143, fy=0.233)
Related
I'm struggling to understand how to overlay a .png with transparency to a video stream.
For some reason, the transparent area is always displayed as black.
Here's what I do:
Loading the image and setting up the environment
import cv2
import numpy as np
from PIL import Image
cap = cv2.VideoCapture(0)
cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("window",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
dim = (640,480)
alpha=0.0
foreground = cv2.imread('png.png',cv2.IMREAD_UNCHANGED)
rows,cols,channels = foreground.shape
Adding an artificial alhpa layer to the frame and overlaying the loaded image
def logoOverlay(image,logo,alpha=1.0,x=0, y=0, scale=1.0):
(h, w) = image.shape[:2]
image = np.dstack([image, np.ones((h, w), dtype="uint8") * 255])
overlay = cv2.resize(logo, None,fx=scale,fy=scale)
(wH, wW) = overlay.shape[:2]
output = image.copy()
# blend the two images together using transparent overlays
try:
if x<0 : x = w+x
if y<0 : y = h+y
if x+wW > w: wW = w-x
if y+wH > h: wH = h-y
overlay=cv2.addWeighted(output[y:y+wH, x:x+wW],alpha,overlay[:wH,:wW],1-alpha,0)
output[y:y+wH, x:x+wW ] = overlay
except Exception as e:
print("Error: Logo position is overshooting image!")
print(e)
output= output[:,:,:3]
return output
Calling this function every frame:
while(True):
ret, frame = cap.read()
frame = cv2.flip(frame,1)
frame = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)
frame = logoOverlay(frame,foreground,alpha=alpha,scale=1,y=100,x=100)
cv2.imshow('window',frame)
thanks for your help, highly appreciated!
FP
I am trying to detect a simple object, and then detect his color. I have created my own CUSTOM HAARCASCADE but it converts the camera's image to grayscale. Maybe I could detect the object through a mask? I have not found any articles on this online.
Here is my code if u need it:
import cv2
import numpy as np
################################################################
#path = 'haarcascades/haarcascade_eye.xml' # PATH OF THE CASCADE
path = 'haarcascades/Azuolas.xml' # PATH OF THE CASCADE
#path = 'haarcascades/haarcascade_frontalface_default.xml' # PATH OF THE CASCADE
#path = 'haarcascades/haarcascade_smile.xml' # PATH OF THE CASCAD
objectName = 'Azuolas' # OBJECT NAME TO DISPLAY
frameWidth= 640 # DISPLAY WIDTH
frameHeight = 480 # DISPLAY HEIGHT
color= (255,0,255)
#################################################################
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
def empty(a):
pass
# CREATE TRACKBAR
cv2.namedWindow("Result")
cv2.resizeWindow("Result",frameWidth,frameHeight+100)
cv2.createTrackbar("Scale","Result",400,1000,empty)
cv2.createTrackbar("Neig","Result",8,50,empty)
cv2.createTrackbar("Min Area","Result",0,100000,empty)
cv2.createTrackbar("Brightness","Result",180,255,empty)
# LOAD THE CLASSIFIERS DOWNLOADED
cascade = cv2.CascadeClassifier(path)
while True:
# SET CAMERA BRIGHTNESS FROM TRACKBAR VALUE
cameraBrightness = cv2.getTrackbarPos("Brightness", "Result")
cap.set(10, cameraBrightness)
# GET CAMERA IMAGE AND CONVERT TO GRAYSCALE
success, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# DETECT THE OBJECT USING THE CASCADE
scaleVal =1 + (cv2.getTrackbarPos("Scale", "Result") /1000)
neig=cv2.getTrackbarPos("Neig", "Result")
objects = cascade.detectMultiScale(gray,scaleVal, neig)
# DISPLAY THE DETECTED OBJECTS
for (x,y,w,h) in objects:
print(objectName ,"is in my fov")
area = w*h
minArea = cv2.getTrackbarPos("Min Area", "Result")
if area >minArea:
cv2.rectangle(img,(x,y),(x+w,y+h),color,3)
cv2.putText(img,objectName,(x,y-5),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,color,2)
roi_color = img[y:y+h, x:x+w]
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
Thanks in advance!!!!
I'm familiar with cv2, but haven't used it in years, so bear with me here. What I think you're saying is that when you call cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) it's overwriting the original img to grayscale, even though you've assigned it to the variable gray.
You probably need to copy the image before converting to grayscale. Clone an image in cv2 python
gray = cv2.cvtColor( img.copy(), cv2.COLOR_BGR2GRAY )
am using hough transform for detecting circles in the real time video frame.in hough circles function the first parameter is to pass as an single channel image.i dont know how to do this. it continously shows error in that part.
the code am using :
import cv2
import cv2 as cv
from matplotlib import pyplot as plt
from scipy.ndimage import imread
import numpy as np
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
cam_capture = cv2.VideoCapture(0)
cv2.destroyAllWindows()
upper_left = (50, 50)
bottom_right = (300, 300)
def sketch_transform(image):
## print(image)
## print("2")
## #gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
## print(image)
## print("3")
## gray = 255-gray
## ret, thresh = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)
## image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
## print(image)
## print("4")
## #image = cv2.drawContours(image, contours, -1,(0,0,255),3)
## print(image)
## print("4")
circle_detect(image)
return image
def circle_detect(image):
#image1=str(image)
#mage = cv2.imread(image, cv2.IMREAD_COLOR)
print (image)
print("k")
image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
circles = cv2.HoughCircles(image,cv2.HOUGH_GRADIENT,1,20,
param1=90,param2=30,minRadius=0,maxRadius=100)
print(circles)
circles = np.uint16(np.around(circles))
## for i in circles[0,:]:
## # draw the outer circle
## cv2.circle(image,(i[0],i[1]),i[2],(0,255,0),2)
## # draw the center of the circle
## cv2.circle(image,(i[0],i[1]),2,(0,0,255),3)
return circles
while True:
_, image_frame = cam_capture.read()
#Rectangle marker
r = cv2.rectangle(image_frame, upper_left, bottom_right, (100, 50, 200), 5)
rect_img = image_frame[upper_left[1] : bottom_right[1], upper_left[0] : bottom_right[0]]
sketcher_rect = rect_img
print(sketcher_rect)
print("1")
sketcher_rect = sketch_transform(sketcher_rect)
#Conversion for 3 channels to put back on original image (streaming)
#sketcher_rect_rgb = cv2.cvtColor(sketcher_rect, cv2.COLOR_GRAY2RGB)
#Replacing the sketched image on Region of Interest
image_frame[upper_left[1] : bottom_right[1], upper_left[0] : bottom_right[0]] = sketcher_rect
cv2.imshow("Sketcher ROI", image_frame)
if cv2.waitKey(1) == 13:
break
cam_capture.release()
cv2.destroyAllWindows()
am new to opencv and i have been struggling for last four days for detecting circles in a video frame.as an image the detction is good but it make some trouble in video frame.
the output is:
Traceback (most recent call last):
File "/home/pi/Downloads/Pi-tracker-master/fgroi.py", line 62, in <module>
sketcher_rect = sketch_transform(sketcher_rect)
File "/home/pi/Downloads/Pi-tracker-master/fgroi.py", line 27, in sketch_transform
circle_detect(image)
File "/home/pi/Downloads/Pi-tracker-master/fgroi.py", line 36, in circle_detect
image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
cv2.error: OpenCV(3.4.4) /home/pi/packaging/opencv-python/opencv/modules/imgproc/src/color.hpp:255: error: (-2:Unspecified error) in function 'cv::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with VScn = cv::Set<1>; VDcn = cv::Set<3, 4>; VDepth = cv::Set<0, 2, 5>; cv::SizePolicy sizePolicy = (cv::SizePolicy)2u; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
> 'VScn::contains(scn)'
> where
> 'scn' is 3
What I'm trying to do is to make a screenshot of a number with pyautogui and tranform the number to a string with pytesseract. The code:
import pyautogui
import time
import PIL
from PIL import Image
import pytesseract
pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)//Tesseract-OCR//tesseract'
# Create image
time.sleep(5)
image = pyautogui.screenshot('projects/output.png', region=(1608, 314, 57, 41))
# Resize image
basewidth = 2000
img = Image.open('projects/output.png')
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
img.save('projects/output.png')
col = Image.open('projects/output.png')
gray = col.convert('L')
bw = gray.point(lambda x: 0 if x<128 else 255, '1')
bw.save('projects/output.png')
# Image to string
screen = Image.open('projects/output.png')
print(pytesseract.image_to_string(screen, config='tessedit_char_whitelist=0123456789'))
Now it seems that pytesseract doesn't accept the screenshot pyautogui creates. The code runs fine without problems but prints an empty string. If I create an image in paint however, and save it as 'output.png' to the correct folder exactly like the screenshot otherwise made, it does work.
Image output after resize and adjustments
Anyone has an idea where I'm missing something?
Modify the path and try the following:
import numpy as np
from numpy import *
from PIL import Image
from PIL import *
import pytesseract
import cv2
src_path = "C:\\Users\\USERNAME\\Documents\\OCR\\"
def get_region(box):
#Grabs the region of the box coordinates
im = ImageGrab.grab(box)
#Change size of image to 200% of the original size
a, b, c, d = box
doubleX = (c - a) * 2
doubleY = (d - b) * 2
im.resize((doubleX, doubleY)).save(os.getcwd() + "\\test.png", 'PNG')
def get_string(img_path):
# Read image with opencv
img = cv2.imread(img_path)
# Convert to gray
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply dilation and erosion to remove some noise
kernel = np.ones((1, 1), np.uint8)
img = cv2.dilate(img, kernel, iterations=1)
img = cv2.erode(img, kernel, iterations=1)
# Write image after removed noise
cv2.imwrite(src_path + "removed_noise.png", img)
# Apply threshold to get image with only black and white
#img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
# Write the image after apply opencv to do some ...
cv2.imwrite(src_path + "thres.png", img)
# Recognize text with tesseract for python
result = pytesseract.image_to_string(Image.open(src_path + "thres.png"))
return result
def main():
#Grab the region of the screenshot (box area)
region = (1354,630,1433,648)
get_region(region)
#Output results
print ("OCR Output: ")
print (get_string(src_path + "test.png"))
Convert it to a numpy array, pytesseract accepts those.
import numpy as np
import pyautogui
img = np.array(pyautogui.screenshot())
print(pytesseract.image_to_string(img, config='tessedit_char_whitelist=0123456789'))
Alternatively I would recommend 'mss' for screenshots as they are much faster.
import mss
with mss.mss() as sct:
img = np.array(sct.grab(sct.monitors[1]))
print(pytesseract.image_to_string(img, config='tessedit_char_whitelist=0123456789'))
I am doing camera calibration in ubuntu 14 using OpenCV with python
I executed the code attached with this post for camera calibration. A part of the code seems to work properly as the camera detected the corners properly. But there was this error "OpenCV Error: Assertion failed (nimages > 0) in calibrateCamera, file /home/aljovjoy/Downloads/opencv-2.4.9/modules/calib3d/src/calibration.cpp, line 3415 "
This error should be rectified to complete the camera calibration.Please tell me how to remove this error to make it work
import numpy as np
import cv2
import glob
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objpoints = []
imgpoints = []
images = glob.glob('/usr/local/share/OpenCV/samples/cpp/chess*.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret = False
ret, corners = cv2.findChessboardCorners(gray, (9,6))
if ret == True:
cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (9,6), corners, ret)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Thanks in advance