简体   繁体   English

如何从图像中提取签名(Python脚本)?

[英]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: 我本人只是刚开始使用Python,但认为我可以解决一个问题-提出了以下建议:

#!/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. 该脚本将抓取您的signature.jpg,使用找到的所有白色像素作为透明背景,然后将其写入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. 我使用HSV色彩空间将签名与背景分开,如果签名或背景具有其他颜色,这很容易适应。

I have not found python bindings for the copyTo() -method used by @BahramdunAdil. 我没有找到@BahramdunAdil使用的copyTo() -方法的python绑定。 You could use numpy.copyto() functionality instead. 您可以改用numpy.copyto()功能。 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. 或者,您可以采用阈值签名并使用@ renedv1的方法来保存Alpha图像。 Use the sign_masked image for that. sign_masked使用sign_masked图像。 Because of the HSV-range you can create a cleaner result. 由于具有HSV范围,您可以创建更清晰的结果。 (Note: account for the fact that sign_masked has a black background) (注意:考虑到sign_masked具有黑色背景这一事实)

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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