-1

i have images of puzzle pieces and i am working on an algorithm to match a puzzle. i want to show a image of the current result after finding a match for each puzzle. puzzle piece. i want to past all the images in one plane.. but cant find the exact coordinate where the image need to be posted in order for it to mach with the previous piece. but cant seem to find a way to make the background blank using opencv. for now the pixels are black(0,0,0). any idea how i can make back pixels blank and past on a different image?

After trying the suggested methods. enter image description here

the above image is what i manged to get using these codes

def show_results(results, puzzle):
    final = Image.new('RGBA', (300 * COL_NUM, 300 * ROW_NUM))
    border = 100
    keys = list(results.keys())
    X, Y = border, border
    x, y = border, border
    for i in keys:
        image = puzzle[results[i]].img
        corners = puzzle[results[i]].corners
        image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2RGBA)
        image[np.all(image == [0, 0, 0, 255], axis=2)] = [0, 0, 0, 0]
        corner0 = corners[0]
        x = X-corner0[0]
        y = Y-corner0[1]
        img = Image.fromarray(np.uint8(image))
        final.paste(img, (x, y))
        corner1 = corners[1]
        X = X + (corner1[0]-corner0[0])
        Y = Y + (corner1[1]-corner0[1])
    final.save('current.png')
    # cv2.imshow("result",final)
    # cv2.waitKey(0)

how to fix this problem. there might be a problem in the format that i used for pasting. but i can figure it out

Eshaka
  • 974
  • 1
  • 14
  • 38
  • 1
    This seems like it would help: http://benjamintan.io/blog/2018/05/24/making-transparent-backgrounds-with-numpy-and-opencv-in-python/ – Andrey Mikus Apr 02 '19 at 09:19
  • Not sure if this was fixed, but if not, do you mean to convert the black pixels to white? Or do you want them transparent? – Shawn Mathew Apr 02 '19 at 15:02
  • https://stackoverflow.com/a/37198079/3962537 – Dan Mašek Apr 02 '19 at 15:46
  • @AndreyMikus i tried according to that link. image seems to have no back ground. but it still cant place on top of another. it still take the whole size of the image clear the pixels accordingly. i will add the codes and a image to the question for you to see – Eshaka Apr 03 '19 at 01:43
  • @ShawnMathew i will change that question, please take a look – Eshaka Apr 03 '19 at 01:44
  • @Eshaka if you're looking to place images on top of each other, you'll need to add/use the alpha channel to have a transparent background (like in a PNG image). If you can confirm this is what you want, we can help with that. – Shawn Mathew Apr 03 '19 at 14:51

1 Answers1

1

I'm guessing your input image does not have a transparent background by default. The convert_to_png() funciton will add the alpha channel to your image

def convert_to_png(img): 
    fin_img = cv2.cvtColor(img, cv2.COLOR_RGB2RGBA)
    b, g, r, alpha = cv2.split(fin_img)
    alpha[:, :] = 0.0
#    plt.imshow(alpha);plt.title('alpha image');plt.show()     
#    plt.imshow(img);plt.title('original image');plt.show()   
    alpha[np.where((img != (255, 255, 255)).any(axis = 2))] = 255

    fin_img[:,:, 0] = img[:,:,0]
    fin_img[:,:, 1] = img[:,:,1]
    fin_img[:,:, 2] = img[:,:,2]
    fin_img[:,:, 3] = alpha[:,:]

#    plt.imshow(fin_img);plt.title('fin image');plt.show()
    return fin_img

Once you get the image with the alpha channel, you can paste the image over each other like so:

y1, y2 = new_loc[1], new_loc[1] + img.shape[0]
x1, x2 = new_loc[0], new_loc[0] + img.shape[1]

alpha_s = img[:, :, 3] / 255.0
alpha_l = 1.0 - alpha_s

for c in range(0, 3):
    fin_img[y1:y2, x1:x2, c] = (alpha_s * img[:, :, c] +
                              alpha_l * img[y1:y2, x1:x2, c])

Here fin_img is a 3-channel output image

Shawn Mathew
  • 2,198
  • 1
  • 14
  • 31