简体   繁体   中英

How to extract signature from an image (python script)?

Here is a sample image of signature :

样品

How to get the signature from this image without background so that I can paste it over user image. What if background is not white?

I have tried this , how to customize it for different background colors?

Just started with Python myself but thought I'd have a go at a solution - came up with this:

#!/usr/bin/python2

import cv2
import numpy as np

file_name = "/tmp/signature.jpg" # your signature image...

image = cv2.imread(file_name, 1)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGBA)
# note: [R,G,B,255] below, so first 3 numbers [255,255,255] are your white 
# background pixels to be converted to RGBA setting of [0,0,0,0] (transparent)
image[np.all(image == [255, 255, 255, 255], axis=2)] = [0, 0, 0, 0]

cv2.imwrite("/tmp/signature-transparent.png", image)

This script will grab your signature.jpg, make a transparent background from all the white pixels it finds, then write it to signature.png.

Looks like this:

透明背景图片

However it's not exactly clean around the edges! Anyone out there who can sort that?

You should consider the steps below: for example, pretend it is your user image:

在此处输入图片说明

Now go with these steps:

cv::namedWindow("result", cv::WINDOW_FREERATIO);
cv::Mat signatureImg = cv::imread(R"(izrMq.jpg)");
cv::Mat userImg = cv::imread(R"(user_image.jpg)");

// make a mask
cv::Mat mask;
cv::cvtColor(signatureImg, mask, cv::COLOR_BGR2GRAY);
cv::threshold(mask, mask, 150, 255, cv::THRESH_BINARY_INV);

// now copy
cv::Mat submat = userImg(cv::Rect(userImg.cols-signatureImg.cols, userImg.rows-signatureImg.rows, signatureImg.cols, signatureImg.rows));
signatureImg.copyTo(submat, mask);

cv::imshow("result", userImg);

cv::waitKey();

And it is the result:

在此处输入图片说明

Hope it helps!

It is quite a process, mainly because there are a number of steps to add an image on top of an image of a different size. I advice you to check out all intermediate steps in the code below, to understand what happens.

I used the HSV-colorspace to separate the signature from the background, this is easy to adapt if the signature or background have other colors.

I have not found python bindings for the copyTo() -method used by @BahramdunAdil. You could use numpy.copyto() functionality instead. For that I'll refer you to this answer .

I used a different technique: to add the image on top of another, first a subimage of the same size as the signature is created. The signature can be added to the subimage, which is then put back in the main image.

Alternatively, you can take the thresholded signature and use @renedv1's method to save an alpha image. Use the sign_masked image for that. Because of the HSV-range you can create a cleaner result. (Note: account for the fact that sign_masked has a black background)

Result:
在此处输入图片说明

Code:

    import numpy as np 
    import cv2
    # load image
    sign = cv2.imread("sign.jpg")
    bg_img = cv2.imread("green_area.jpg")

     # Convert BGR to HSV
    hsv = cv2.cvtColor(sign, cv2.COLOR_BGR2HSV)

    # define range of HSV-color of the signature
    lower_val = np.array([0,0,0])
    upper_val = np.array([179,255,150])

    # Threshold the HSV image to get a mask that holds the signature area
    mask = cv2.inRange(hsv, lower_val, upper_val)
    # create an opposite: a mask that holds the background area
    mask_inv= cv2.bitwise_not(mask)

    # create an image of the signature with background excluded
    sign_masked = cv2.bitwise_and(sign,sign,mask=mask)

    # get the dimensions of the signature
    height, width = sign.shape[:2]

    # create a subimage of the area where the signature needs to go
    placeToPutSign = bg_img[0:height,0:width]
    # exclude signature area 
    placeToPutSign_masked = cv2.bitwise_and(placeToPutSign, placeToPutSign, mask=mask_inv)
    # add signature to subimage
    placeToPutSign_joined = cv2.add(placeToPutSign_masked, sign_masked)

    # put subimage over main image
    bg_img[0:height,0:width] = placeToPutSign_joined

    # display image
    cv2.imshow("result", bg_img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM