Pha trộn ảnh trong OpenCV (blending)

  Nov 10, 2020      2m
   

OpenCV - Tut 4.2: Blending

Pha trộn ảnh trong OpenCV (blending)

Tut 4.2: Blending

Blending Minh tạm dịch là pha trộn ảnh đi. Nó sẽ tạo ra hiệu ứng mình nhìn thấy ảnh nọ trên ảnh kia (nhờ hiệu ứng trong suốt, tùy thuộc vào độ trong suốt). Kỹ thuật này "thần dân" Photoshop rành lắm nè.

Khi mình dùng phần mềm Photoshop thì ta chỉ cần biết ở mức độ sử dụng - kết quả dự kiến sẽ trông ra sao và tùy chỉnh tham số để đạt được hiệu ứng đó. Còn đối với trai "ngành" Xử Lý Ảnh thì cần nắm "giải thuật" pha trộn màu (blending) chạy ra sao, tham số có lý nghĩa gì.

Trong phạm vi bài viết này, Minh dùng ở mức độ API của thư viện OpenCV thôi nhe :)). Đôi khi, trực quan hóa kết quả Xử Lý Ảnh sẽ cần đến blending. Ví dụ như tracking xe di chuyển, để cho đẹp mình blending chiếc xe quá khứ vào ảnh hiện tại sau cùng cho nó trông đẹp và "art" :">.

Nhà nào mà chẳng có mái! Nãy giờ chém bay nóc rồi, bắt tay vào gõ phím thôi.

Bước được mong chờ nhất => download ảnh mẫu thôi :">

pretty_girl.jpg

pretty_girl.jpg

Ghi chú: do ảnh này mình tìm kiếm và lấy trên mạng, nên không biết chính chủ để credit vào; ảnh này được sử dụng vào mục đích học tập / nghiên cứu (giáo dục), và mang tính chất phi thương mại!

Nguồn lụm ảnh: https://chieuta.com/hinh-anh-hot-girl-co-doi-mat-biet-noi-say-dam-nguoi-nhin.html

Blending hai ảnh trong OpenCV

Thư viện OpenCV hỗ trợ hàm cv2.addWeighted cho phép trộn hai ảnh.

Giải thích tham số:

  • src1: ảnh #1
  • alpha: trọng số mức sáng của ảnh #1
  • src2: ảnh #2
  • beta: trọng số mức sáng của ảnh #2
  • gamma: điều chỉnh sáng pha trộn

Blending ảnh pha màu theo công thức:

dst = src1*alpha + src2*beta + gamma;

Minh đã viết thành một hàm cho phép blend ảnh foreground lên trên ảnh background, với kích thước ảnh foreground <= kích thước ảnh background.

Download thêm ảnh "foreground" nhe.

minh.jpg

minh.jpg

blending.py

import cv2

IMAGE_BG = "pretty_girl.jpg"
IMAGE_FG = "minh.jpg"
OUT_NAME = "blend.jpg"

BLEND_X = 0.1
BLEND_Y = 0.05
BLEND_OPAQUE = 0.5

def blend(bg, fg, x, y, opaque=1.0, gamma=0):
    """
        bg: background (color image)
        fg: foreground (color image)
        x, y: top-left point of foreground image (percentage)
    """
    h, w = bg.shape[:2]
    x_abs, y_abs = int(x*w), int(y*h)
    
    fg_h, fg_w = fg.shape[:2]
    patch = bg[y_abs:y_abs+fg_h, x_abs:x_abs+fg_w, :]
    
    blended = cv2.addWeighted(src1=patch, alpha=1-opaque, src2=fg, beta=opaque, gamma=gamma)
    result = bg.copy()
    result[y_abs:y_abs+fg_h, x_abs:x_abs+fg_w, :] = blended
    return result

def main(bg_path, fg_path):
    img_bg = cv2.imread(bg_path)
    img_fg = cv2.imread(fg_path)
    result = blend(bg=img_bg, fg=img_fg, x=BLEND_X, y=BLEND_Y, opaque=BLEND_OPAQUE)
    cv2.imwrite(OUT_NAME, result)
    print("\x1b[1;%dm" % (31) + "Saved image @ %s" % OUT_NAME + "\x1b[0m")
    pass

if __name__ == "__main__":
    main(bg_path=IMAGE_BG, fg_path=IMAGE_FG)
    print('-------')
    print('* Follow me @ ' + "\x1b[1;%dm" % (34) + ' https://www.facebook.com/kyznano/' + "\x1b[0m")
    print('* Minh fanpage @ ' + "\x1b[1;%dm" % (34) + ' https://www.facebook.com/minhng.info/' + "\x1b[0m")    
    print('* Join GVGroup @ ' + "\x1b[1;%dm" % (34) + 'https://www.facebook.com/groups/ip.gvgroup/' + "\x1b[0m")    
    print('* Thank you ^^~')

Chạy script blend màu:

$ python blending.py
Saved image @ blend.jpg
-------
* Follow me @  https://www.facebook.com/kyznano/
* Minh fanpage @  https://www.facebook.com/minhng.info/
* Join GVGroup @ https://www.facebook.com/groups/ip.gvgroup/
* Thank you ^^~

Ảnh kết quả:

blend.jpg

blend.jpg

Bài viết tham khảo:

Bài viết tiếp theo: Tut 5: Xử lý ảnh - OpenCV ảnh nhị phân


Cảm ơn bạn đã theo dõi bài viết. Hãy kết nối với tớ nhé!


Danh sách bài viết series OpenCV: