OpenCV의 이미지 마스킹

Sahil Bhosale 2023년6월21일
OpenCV의 이미지 마스킹

이미지의 일부를 필터링한 다음 이 필터링된 부분을 다른 이미지와 결합하려는 경우 마스킹을 사용하여 수행할 수 있습니다. OpenCV에서 Bitwise AND 연산자는 두 개의 서로 다른 이미지를 하나로 결합하거나 한 이미지의 일부를 다른 이미지로 결합하는 데 사용됩니다.

비트 AND는 일반적으로 두 배열/스칼라/이미지의 요소당 비트 논리 조합을 계산합니다. 이 기사에서는 OpenCV 라이브러리의 Bitwise AND 연산자를 사용하여 이미지에 마스킹을 적용하는 방법을 살펴봅니다.

Bitwise AND 연산자를 사용하여 OpenCV에서 마스킹 수행

비트 연산자는 OpenCV에서 사용되므로 이미지의 일부를 추출하거나 필터링하여 이미지를 묘사하고 직사각형이 아닌 ROI(관심 영역)로 작동할 수 있습니다. OpenCV에서 Bitwise AND 연산을 수행하기 위해 bitwise_and() 메서드를 사용합니다.

bitwise_and()의 구문은 다음과 같습니다.

cv.bitwise_and(img_array_1, img_array_2, destination_array, masking)

bitwise_and() 메서드는 4개의 인수를 사용합니다.:

  1. img_array_1: 배열 형식의 이미지 1 데이터.
  2. img_array_2: 어레이 형식의 이미지 2 데이터.
  3. destination_array: 입력 배열과 크기 및 유형이 동일한 출력 이미지. 선택적 매개변수입니다.
  4. 마스킹: 결과 이미지에서 수행되는 마스크 작업입니다. 선택적 매개변수입니다.

아래 예제의 도움으로 bitwise_and()를 사용하여 마스킹이 어떻게 작동하는지 살펴보겠습니다.

하나는 로고 이미지이고 다른 하나는 자동차 이미지인 두 개의 이미지가 있고 자동차 이미지의 왼쪽 상단에 로고를 추가해야 한다고 가정합니다. 따라서 이를 달성하기 위해 OpenCV를 사용하여 Python에서 아래 코드를 작성합니다.

먼저 logocar 이미지의 이미지를 모두 읽어들인 다음 각각 img1img2 변수에 할당해야 합니다. 마스킹을 통해 ROI를 사용하여 자동차 이미지의 왼쪽 상단에 로고를 적용하거나 표시합니다.

이를 위해 우리 로고인 img2에서 row, colschannels 데이터를 추출합니다. 이 로고를 자동차 이미지의 왼쪽 상단 모서리에 배치하고 싶기 때문에 아래와 같이 img1(0,0) 좌표에 img2rowscols를 적용합니다.

코드 조각:

# import opencv
import cv2 as cv

# Loading images
img1 = cv.imread("car.jpg")
img2 = cv.imread("logo.png")

# We want to put the logo on the top-left corner, so we create ROI
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]

# Now create a mask of the logo and create its inverse mask, also
img2gray = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)

# Now black out the area of the logo in ROI
img1_bg = cv.bitwise_and(roi, roi, mask=mask_inv)

# Take only the region of the logo from the logo image.
img2_fg = cv.bitwise_and(img2, img2, mask=mask)

# Put logo in ROI and modify the main image
dst = cv.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst

cv.imshow("mask", mask)
cv.imshow("inv_mask", mask_inv)
cv.imshow("img1_bg", img1_bg)
cv.imshow("img2_fg", img2_fg)
cv.imshow("Final image", img1)
cv.waitKey(0)
cv.destroyAllWindows()

그런 다음 로고의 마스크와 반전 마스크를 만들어야 합니다. 이를 위해 초기에 로고의 배경색을 회색으로 변경하고 이를 사용하여 마스크와 역마스크 이미지를 maskmask_inv로 만들었습니다.

이미지의 배경색을 변경하려면 [cvtColor() 메서드를 사용하고 마스크를 만들려면 threshold() 메서드를 사용합니다. 마지막으로 bitwise_not()을 사용하여 이미지를 반전시킵니다.

또한 maskmask_inv 이미지에서 imshow() 함수를 사용하여 마스킹 중에 변경된 사항을 검사할 수 있습니다.

이제 ROI에서 로고 영역을 검게 칠하고 bitwise_and()를 수행하여 로고의 배경, 즉 img2를 가져옵니다. 마찬가지로 로고 이미지에서 로고만 가져오고 bitwise_and()를 수행하여 자동차 이미지의 전경, 즉 img1을 가져옵니다.

여기에서 img1(자동차 이미지) 및 img2(로고 이미지) 이미지에 imshow() 함수를 사용하여 어떤 것이 변경되었는지 확인할 수도 있습니다.

이제 img1img2를 모두 추가하여 ROI에서 자동차 배경이 있는 로고를 얻습니다. 그런 다음 이 출력 이미지를 dst에 넣습니다.

출력:

OpenCV 최종 출력의 이미지 마스킹

나중에 전체 자동차 이미지에 dst를 추가하고 imshow()를 사용하여 최종 출력을 얻습니다. 이것이 우리가 ROI를 사용하여 이미지의 특정 부분을 가져오고 다른 이미지에 추가하여 최종 이미지를 얻는 방법입니다.

Sahil Bhosale avatar Sahil Bhosale avatar

Sahil is a full-stack developer who loves to build software. He likes to share his knowledge by writing technical articles and helping clients by working with them as freelance software engineer and technical writer on Upwork.

LinkedIn

관련 문장 - Python OpenCV