Blurring Number Plate

Hi everyone.

Hello everyone,

I’m trying to blur license plate on video for a project. I managed to create a rectangle which identifies the plate but I can’t blur the interior of this rectangle. I saw that we could use cv2.GaussianBlur() but I can’t set it up (I’m a newbie i know ahah)

Below the code :

import cv2

plate_cascade=cv2.CascadeClassifier("./haarcascade_russian_plate_number.xml")
cap=cv2.VideoCapture(0 + cv2.CAP_DSHOW)

while True:
    ret, frame=cap.read()
    tickmark=cv2.getTickCount()
    gray=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    plate=plate_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3)
    for x, y, w, h in plate:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 10)
        blur_image = cv2.GaussianBlur(frame,(23, 23), 30)
        blur_image[y:y+plate.shape[0], x:x+plate.shape[1]] = plate

    if cv2.waitKey(1)&0xFF==ord('q'):
        break
    fps=cv2.getTickFrequency()/(cv2.getTickCount()-tickmark)
    cv2.putText(frame, "FPS: {:05.2f}".format(fps), (10, 30), cv2.FONT_HERSHEY_PLAIN, 2, 
    (255, 0, 0), 2)
    cv2.imshow('video', frame)
cap.release()
cv2.destroyAllWindows()

The following error :

ValueError: could not broadcast input array from shape (1,4) into shape (1,4,3)

Thanks in advance.

as a sidenote, you got it backwards. you want to blur the number plate region, not the frame, exluding the number plate

(but what you do is: blur the whole frame, then re-assign the unblurred numberplate)

Oh yes sure… So you mean that i need to replace the frame by the plate ?

I tried this but i have a assertion failed. Whe he mean that the gauss is empty ?

*for x, y, w, h in plate:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 2)
        blur_image = plate[y:y+h, x:x+w]
        blur_image = cv2.GaussianBlur(blur_image,(23, 23), 30)
        plate[y:y+blur_image.shape[0], x:x+blur_image.shape[1]] = blur_image*

what is that supposed to do ? you don’t need that line at all.

(numpy ‘slices’ should work on a refeerence of the image, like cv::Mat does)

as suggested, you could blur the whole picture, and then copy the subregion into the unblurred image. the blur done that way will behave differently around the border of your subregion.

blur_image = cv2.GaussianBlur(frame, (23, 23), 30) # blur everything
for x, y, w, h in plate: # coordinates
    frame[y:y+h, x:x+w] = blur_image[y:y+h, x:x+w] # copy subregion from blurred version
    cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 2) # draw box on top

this tells me that you’re a little confused with your variables:

plate is all the rectangles resulting from the multi-scale detection that uses the cascade classifier. it’s a list of coordinates (x,y,w,h).

you have no use for plate.shape at all.

You’ve right i’m really lost…
I’m just a little System Administrator and i’m trying to learn Python and Opencv at the same time for someone and i have a dead line.
I’m trying to find what i want on the net but i don’t understand everything. That’s why i have no response for @berak and i’m sorry for that.

@crackwitz
I made the changes you indicated previously but i have the same issue. The first error was
NameError: name ‘blur_image’ is not defined

Pretty logic because i’m in a whyle loop so i declared the variable at the beginning. After that it seams to work. But when the camera find the plate i have the same error that before. I don’t understand ( I know it’s just a matter of logic but I can’t figure it out…)

this all you need:

        frame[y:y+h, x:x+w] = cv2.GaussianBlur(frame[y:y+h, x:x+w],(23, 23), 30)
 

note the slice invocation on the left side, python does not have references (as in c++)