Search code examples
pythonopencvgeometrystandard-librarydlib

Get a section of an image, and then the center of that square, without any external libraries?


I'm working on a project that requires me to extract a face:

enter image description here

And I've done so, with dlib. The next step is to extract the keypoints from that region and store them. The problem, is that I can't extract that region.

I'm using OpenCV's sub rectangle function:

for k, d in enumerate(dets):

    a = d.left()
    b = d.top()
    c = d.right()
    d = d.bottom()

    print ("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(k, a, b, c, d))
#   showImg(img1, "Image")

    temp1 = img1
    cv2.rectangle(temp1, (a, b), (c, d), (255, 0, 0), 2)
#   showImg(temp1, "Face")

    aa = a
    print ("Selection Size: " + str(aa))


#   x1 = (a, b)
#   x2 = (d, b)
#   y1 = (a, d)
#   y2 = (c, d)
#   r, z = (x1+x2/2, y1+y2/2)

    x = ((a+d)/2)
    y = ((b+c)/2)

    temp2 = cv2.getRectSubPix(img1, (aa,aa), (x,y))
    showImg(temp2, "Face Image")

And despite reading multiple geometry and calculus tutorials, I can't get the math right. It keeps coming out too small, or off center. I finally dicerned that it needed to take the whole image into account, not just the frame:

enter image description here

But that's not accureate either, the bottom corner is the image, not the frame center.

And to make it even harder, I have to use cv2.getRectSubPix. There's something wrong with my numpy and it won't process pictures correctly, and PIL/Pillow/PythonImageLybrary is giving me installation issures. It has to be all in OpenCV.

Can anyone help me with this issue?


Solution

  • If you can't use numpy slicing, you should fix your code:

    here is your main error:

    x = ((a+d)/2)
    y = ((b+c)/2)
    

    that is equal to:

    x = ((left+bottom)/2)
    y = ((top+right)/2)
    

    one more error is re-declaring variable 'd' that what initially 'detection rect' and comes to 'bottom'

    So the solution can look like:

    c = d.center();
    center = (c.x, c.y)
    patch_size = (d.width(), d.height())
    cv2.rectangle(temp1, patch_size, center, (255, 0, 0), 2)