Reputation: 706
I am trying create a circle and blur the contents in OpenCV. However, I am able to make the circle, but I am not able to blur that part. My code is given below. Please help me out
import io
import picamera
import cv2
import numpy as np
import glob
from time import sleep
from PIL import ImageFilter
image = cv2.imread('/home/pi/Desktop/cricle-test/output_0020.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faceCascade = cv2.CascadeClassifier('/home/pi/Desktop/Image-Detection-test/haarcascade_frontalface_alt.xml')
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
print "Found {0} faces!".format(len(faces))
# Draw a circle around the faces and blur
for (x, y, w, h) in faces:
sub = cv2.circle(image, ( int((x + x + w )/2), int((y + y + h)/2 )), int (h / 2), (0, 255, 0), 5)
cv2.blur(image(x,y,w,h),(23,23), 40000)
cv2.imwrite("/home/pi/Desktop/cricle-test/output_0020.jpg" ,image)
Upvotes: 3
Views: 9088
Reputation: 11420
For it to work you need to do a couple of things, first cv2.blur
needs a destination and not a number. This can be achieved with:
image[y:y+h, x:x+w] = cv2.blur(image[y:y+h, x:x+w] ,(23,23))
Since you are saving the image to the same file in every loop, you can just save it after the loop.
Since you wanted a circular bur, you need to create a circular mask, then apply it to the image, here is how your code will look like (only the loop part):
# create a temp image and a mask to work on
tempImg = image.copy()
maskShape = (image.shape[0], image.shape[1], 1)
mask = np.full(maskShape, 0, dtype=np.uint8)
# start the face loop
for (x, y, w, h) in faces:
#blur first so that the circle is not blurred
tempImg [y:y+h, x:x+w] = cv2.blur(tempImg [y:y+h, x:x+w] ,(23,23))
# create the circle in the mask and in the tempImg, notice the one in the mask is full
cv2.circle(tempImg , ( int((x + x + w )/2), int((y + y + h)/2 )), int (h / 2), (0, 255, 0), 5)
cv2.circle(mask , ( int((x + x + w )/2), int((y + y + h)/2 )), int (h / 2), (255), -1)
# oustide of the loop, apply the mask and save
mask_inv = cv2.bitwise_not(mask)
img1_bg = cv2.bitwise_and(image,image,mask = mask_inv)
img2_fg = cv2.bitwise_and(tempImg,tempImg,mask = mask)
dst = cv2.add(img1_bg,img2_fg)
cv2.imwrite("/home/pi/Desktop/cricle-test/output_0020.jpg" ,dst)
This seems to work, at least in my test, you may try adjusting the kernel size (this (23,23) in the blur) to get less or more blurred image, for example, try this code with (7,7) it will have more details.
If you want to use ellipses instead of circles just change the circle instruction to:
cv2.ellipse(mask , ( ( int((x + x + w )/2), int((y + y + h)/2 )),(w,h), 0), 255, -1)
The same way you can change it to a rectangle, polygon, or any other shape.
Upvotes: 12