웹사이트 검색

이미지 처리 5부: 산술, 비트 단위 및 마스킹


이미지 처리 시리즈의 5부에서는 산술 및 비트 연산과 Python의 이미지 마스킹에 대해 자세히 설명합니다.

여기에서 마스크 학습 모험을 시작하기 전에 이전 기사를 검토하는 것이 좋습니다.

환경 설정

다음 코드 행은 아래 제공된 모든 응용 프로그램에서 사용됩니다. 거대한 코드 블록을 읽을 필요가 없도록 대신 여기에 포함시킬 것입니다.

군더더기를 줄이는데 도움이 됩니다 :)

# importing numpy to work with pixels
import numpy as np

# importing argument parsers
import argparse

# importing the OpenCV module
import cv2


# initializing an argument parser object
ap = argparse.ArgumentParser()

# adding the argument, providing the user an option
# to input the path of the image
ap.add_argument("-i", "--image", required=True, help="Path to the image")

# parsing the argument
args = vars(ap.parse_args())

# reading the image location through args
# and reading the image using cv2.imread
image = cv2.imread(args["image"])

Python을 사용한 이미지의 산술 연산

산술 연산을 통해 이미지의 많은 측면을 향상시킬 수 있습니다.

조명, 그림자, 빨강, 파랑 및 녹색 색상 향상 작업을 할 수 있습니다.

응용 프로그램의 많은 이미지 필터는 동일한 방법을 사용하여 사진을 변경하고 아름답게 합니다.

이제 모든 코드를 시작하겠습니다!

먼저 제한이 255를 초과할 수 있는지 또는 0을 초과할 수 있는지 이해하기 위해 2550을 제공하는 간단한 테스트를 수행할 수 있습니다.

# printing out details of image min, max and the wrap around
print("max of 255 :", str(cv2.add(np.uint8([200]), np.uint8([100]))))
print("min of 0 :", str(cv2.subtract(np.uint8([50]), np.uint8([100]))))

print("wrap around :", str(np.uint8([200]) + np.uint8([100])))
print("wrap around :", str(np.uint8([50]) - np.uint8([100])))

이 예에서는 이미지에 있는 모든 픽셀의 강도를 100씩 증가시킵니다.

# adding pixels of value 255 (white) to the image
M = np.ones(image.shape, dtype="uint8") * 100
added = cv2.add(image, M)
cv2.imshow("Added", added)
cv2.waitKey(0)

NumPy 모듈을 사용하여 이미지와 동일한 크기의 행렬을 구성하고 이미지와 함께 추가하면 됩니다.

이미지를 어둡게 하려면 아래와 같이 이미지의 픽셀 값에서 뺍니다.

# adding pixels of value 0 (black) to the image
M = np.ones(image.shape, dtype="uint8") * 50
subtracted = cv2.subtract(image, M)
cv2.imshow("Subtracted", subtracted)
cv2.waitKey(0)

이렇게 하면 원본 이미지의 두 가지 다른 변형, 즉 하나는 더 밝고 다른 하나는 더 어두워집니다.

비트 연산

우리는 이미지를 마스킹하려고 시도하는 동안 Bitwise 연산을 많이 사용합니다.

OpenCV의 이 기능을 사용하면 이미지에서 우리와 관련된 부분을 필터링할 수 있습니다.

설정

Bitwise 작업을 수행하려면 먼저 작업을 수행할 수 있는 두 개의 변수 또는 이미지가 필요합니다.

따라서 비트 단위 연산을 사용할 수 있는 비트 단위 사각형과 비트 단위 원을 만들어 봅시다.

비트 연산을 수행하려면 이미지가 흑백이어야 합니다.

# creating a square of zeros using a variable
rectangle = np.zeros((300, 300), dtype="uint8")
cv2.rectangle(rectangle, (25, 25), (275, 275), 255, -1)
cv2.imshow("Rectangle : ", rectangle)

# creating a circle of zeros using a variable
circle = np.zeros((300, 300), dtype="uint8")
cv2.circle(circle, (150, 150), 150, 255, -1)
cv2.imshow("Circle : ", circle)

받은 출력 이미지는 다음과 같아야 합니다.

AND 연산과 결합

비트 덧셈은 두 개의 다른 이미지를 더하는 것을 말하며 이미지의 각 픽셀에 대해 AND 연산을 사용하여 표시할 것을 결정합니다.

# the bitwise_and function executes the AND operation
# on both the images
bitwiseAnd = cv2.bitwise_and(rectangle, circle)
cv2.imshow("AND", bitwiseAnd)
cv2.waitKey(0)

원과 사각형을 비트 단위로 더하면 다음과 같은 결과가 나옵니다.

OR 연산으로 선택권 부여

Bitwise OR은 이미지의 각 픽셀에서 수행되는 OR 연산으로 두 이미지의 곱을 제공합니다.

# the bitwise_or function executes the OR operation
# on both the images
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
cv2.waitKey(0)

Bitwise OR 작업을 수행하면 다음과 같은 메시지가 표시됩니다.

XOR 연산의 배타성

cv2 모듈이 제공하는 또 다른 연산은 bitwise_xor 함수를 통해 사용할 수 있는 XOR 연산입니다.

# the bitwise_xor function executes the XOR operation
# on both the images
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
cv2.imshow("XOR", bitwiseXor)
cv2.waitKey(0)

NOT 연산을 사용한 부정

마지막으로 bitwise_not 함수를 사용하여 수행되는 부정 연산이 있습니다.

NOT 작업은 여기서 아무것도 더하거나 빼지 않기 때문에 단일 이미지만 필요합니다.

여기에서는 여전히 두 가지 모두에서 사용하지만 옵션이기도 합니다.

# the bitwise_not function executes the NOT operation
# on both the images
bitwiseNot = cv2.bitwise_not(rectangle, circle)
cv2.imshow("NOT", bitwiseNot)
cv2.waitKey(0)

이 경우 원은 사각형 안에 있으므로 보이지 않습니다.

Python OpenCV를 사용하여 이미지 마스킹

마스킹은 이미지 처리에서 관심 영역 또는 단순히 관심 있는 이미지 부분을 출력하는 데 사용됩니다.

필요하지 않은 이미지 부분을 버릴 수 있으므로 마스킹에 비트 연산을 사용하는 경향이 있습니다.

그럼 마스킹 작업을 시작해볼까요?

이미지 마스킹 과정

마스킹에는 세 단계가 있습니다.

  1. 이미지와 동일한 크기의 검은색 캔버스를 만들고 이름을 마스크로 지정합니다.
  2. 이미지의 아무 도형을 그리고 흰색으로 제공하여 마스크 값을 변경합니다.
  3. 마스크가 있는 이미지에 비트별 ADD 연산을 수행합니다.

동일한 프로세스에 따라 몇 가지 마스크를 만들어 이미지에 사용하겠습니다.

먼저 직사각형 마스크로 작업하겠습니다.

# creating a mask of that has the same dimensions of the image
# where each pixel is valued at 0
mask = np.zeros(image.shape[:2], dtype="uint8")

# creating a rectangle on the mask
# where the pixels are valued at 255
cv2.rectangle(mask, (0, 90), (290, 450), 255, -1)
cv2.imshow("Mask", mask)

# performing a bitwise_and with the image and the mask
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask applied to Image", masked)
cv2.waitKey(0)

이제 서클 마스크로 사용해 봅시다.

# creating a mask of that has the same dimensions of the image
# where each pixel is valued at 0
mask = np.zeros(image.shape[:2], dtype="uint8")

# creating a rectangle on the mask
# where the pixels are valued at 255
cv2.circle(mask, (145, 200), 100, 255, -1)
cv2.imshow("Mask", mask)

# performing a bitwise_and with the image and the mask
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask applied to Image", masked)
cv2.waitKey(0)

모든 것이 제대로 작동하면 다음과 같은 출력을 받아야 합니다.

결론

우리는 마침내 이미지 처리의 핵심을 시작하고 있으며 비트 연산과 마스킹을 이해하는 것이 중요합니다.

그것은 우리가 관심 있는 부분을 차단하거나 이미지의 일부만 가져오는 데 도움이 되므로 매우 유용한 개념입니다.

우리는 괜찮은 속도로 진행하고 있지만 시간을 건너뛰고 끝까지 가고 싶다면 내 손님이 되어주세요!

다음은 Android 및 CameraX OpenCV를 살펴볼 수 있는 기사입니다.

참조

  • 공식 OpenCV 웹사이트
  • OpenCV 시작 소개
  • 이미지 처리를 위한 내 GitHub 저장소
  • 산술 연산 코드
  • 비트 연산 코드
  • 마스킹 코드