알파 채널이 있는 png를 투명 이미지로 붙여넣기 with Python/OpenCV
TL; DR
bg.jpg
의 왼쪽 상단에 png_image.png
(알파 채널이 있는 이미지)를 겹치는 경우의 코드입니다.
import cv2
frame = cv2.imread("bg.jpg")
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED) # アルファチャンネル込みで読み込む
# 貼り付け先座標の設定。とりあえず左上に
x1, y1, x2, y2 = 0, 0, png_image.shape[1], png_image.shape[0]
# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
png_image[:, :, :3] * (png_image[:, :, 3:] / 255)
bg.jpg
alpha.png
결과
간단한 해설
PNG 파일에는 "알파 채널"이라는 각 픽셀의 투명도를 나타내는 데이터가 들어 있습니다. 값 범위는 RGB와 마찬가지로 0-255입니다. 255일 때 100% 유효하고 0일 때 0%(완전 투명)입니다.
# 画像の読み込み
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED) # アルファチャンネル込みで読み込む
보통 cv2.imread()
에서는 [h, w, 3]
의 numpy.ndarray
의 형태가 됩니다만, cv2.IMREAD_UNCHANGED
를 지정해 cv2.imread()
를 호출하면, [h, w, 4]
의 형태가 됩니다. BGR
가 BGRA
와 마지막에 알파 채널이 붙습니다.
이미지를 불러오면 합성합니다. 그렇다고해도, NuPy 의 통상의 행렬 연산으로 합성 가능합니다. 하고 있는 것은, 원래의 배경 화상·묘화하는 화상을, 각각 알파 채널의 수치로 배분해, 더해 놓고 있습니다.
# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
png_image[:, :, :3] * (png_image[:, :, 3:] / 255)
png_image[:, :, 3:]
가 알파 채널의 추출입니다. 알파 채널의 값 영역은 0-255이므로 255로 나누어 0-1의 비율로 합니다. 그리는 이미지에는 계산된 비율을 곱하고 배경 쪽에는 비율의 "남은"을 곱하여 양자를 더하여 최종 이미지를 얻을 수 있습니다.
그건 그렇고, png_image[:, :, 3]
라고 쓰면 행렬의 크기가 맞지 않으면 화가 나므로주의하십시오 (잘못되었습니다).
여록
여러가지 참고가 되는 사이트는 있으면서, 그 자체 즈바리인 코드를 잘 검색할 수 없었기 때문에, 기사를 만들어 보았습니다. (당연히 너무 오히려 쓰지 않을 수도 있습니다)
참고로 한 사이트
import cv2
frame = cv2.imread("bg.jpg")
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED) # アルファチャンネル込みで読み込む
# 貼り付け先座標の設定。とりあえず左上に
x1, y1, x2, y2 = 0, 0, png_image.shape[1], png_image.shape[0]
# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
png_image[:, :, :3] * (png_image[:, :, 3:] / 255)
PNG 파일에는 "알파 채널"이라는 각 픽셀의 투명도를 나타내는 데이터가 들어 있습니다. 값 범위는 RGB와 마찬가지로 0-255입니다. 255일 때 100% 유효하고 0일 때 0%(완전 투명)입니다.
# 画像の読み込み
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED) # アルファチャンネル込みで読み込む
보통
cv2.imread()
에서는 [h, w, 3]
의 numpy.ndarray
의 형태가 됩니다만, cv2.IMREAD_UNCHANGED
를 지정해 cv2.imread()
를 호출하면, [h, w, 4]
의 형태가 됩니다. BGR
가 BGRA
와 마지막에 알파 채널이 붙습니다.이미지를 불러오면 합성합니다. 그렇다고해도, NuPy 의 통상의 행렬 연산으로 합성 가능합니다. 하고 있는 것은, 원래의 배경 화상·묘화하는 화상을, 각각 알파 채널의 수치로 배분해, 더해 놓고 있습니다.
# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
png_image[:, :, :3] * (png_image[:, :, 3:] / 255)
png_image[:, :, 3:]
가 알파 채널의 추출입니다. 알파 채널의 값 영역은 0-255이므로 255로 나누어 0-1의 비율로 합니다. 그리는 이미지에는 계산된 비율을 곱하고 배경 쪽에는 비율의 "남은"을 곱하여 양자를 더하여 최종 이미지를 얻을 수 있습니다.그건 그렇고,
png_image[:, :, 3]
라고 쓰면 행렬의 크기가 맞지 않으면 화가 나므로주의하십시오 (잘못되었습니다).여록
여러가지 참고가 되는 사이트는 있으면서, 그 자체 즈바리인 코드를 잘 검색할 수 없었기 때문에, 기사를 만들어 보았습니다. (당연히 너무 오히려 쓰지 않을 수도 있습니다)
참고로 한 사이트
이미지는 귀여운 무료 소재 모음 소재를 사용했습니다.
Reference
이 문제에 관하여(알파 채널이 있는 png를 투명 이미지로 붙여넣기 with Python/OpenCV), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/smatsumt/items/923aefb052f217f2f3c5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)