Как извлечь подпись из изображения (скрипт Python)? - PullRequest
0 голосов
/ 05 марта 2019

Вот пример изображения подписи:

sample

Как получить подпись на этом изображении без фона, чтобы я мог вставить его поверх пользователяобраз.Что делать, если фон не белый?

Я пробовал это , как настроить его для разных цветов фона?

Ответы [ 3 ]

0 голосов
/ 05 марта 2019

Я только начал работать с 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)

Этот скрипт захватит ваш signature.jpg, сделает прозрачный фон из всехбелые пиксели он находит, а затем записывает его в signature.png.

Выглядит так:

transparent background image

Однако по краям он не совсем чистый!Кто-нибудь может это отсортировать?

0 голосов
/ 05 марта 2019

Это довольно сложный процесс, в основном потому, что есть несколько шагов, чтобы добавить изображение поверх изображения другого размера.Я советую вам проверить все промежуточные шаги в коде ниже, чтобы понять, что происходит.

Я использовал HSV-цветовое пространство для отделения подписи от фона, это легко адаптировать, если подпись или фон имеют другие цвета.

Я не нашел привязок Python для copyTo() -метод, используемый @BahramdunAdil.Вместо этого вы можете использовать numpy.copyto() функциональность.Для этого я отсылаю вас к этому ответу .

Я использовал другую технику: чтобы добавить изображение поверх другого, сначала создается подизображение того же размера, что и подпись.Подпись может быть добавлена ​​к подизображению, которое затем помещается обратно в основное изображение.

Кроме того, вы можете взять пороговую подпись и использовать метод @ renedv1 для сохранения альфа-изображения.Для этого используйте изображение sign_masked.Благодаря HSV-диапазону вы можете добиться более чистого результата.(Примечание: учтите тот факт, что sign_masked имеет черный фон)

Результат:
enter image description here

Код:

    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()
0 голосов
/ 05 марта 2019

Вы должны рассмотреть следующие шаги: например, представьте, что это ваше изображение пользователя:

enter image description here

Теперь выполните следующие действия:

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

И это результат:

enter image description here

Надеюсь, это поможет!

...