파이썬 강의/openCV

파이썬 openCV 9. 산술 연산(arithmetic operation)

마리사라 2020. 11. 21. 14:09
반응형

파이썬 openCV 9번째 강의는 산술 연산입니다. 산술 연산은 매우 쉬운편에 속하니 빠르게 진행하겠습니다.

 

 


0. 산술 연산?

산술연산은 총 3가지 종류가 있습니다. 일반적인 덧셈 연산, 가중치를 줘서 연산하는 알파 연산, 일반적인 뺄셈 연산이 있습니다. 여기서 눈치 채신 분들도 있으시겠지만, 산술 연산은 그저 더하기 빼기 입니다. 이미지를 곱하거나 나눌수는 없으니 더하기 빼기로 이미지를 조작하는걸 말하는겁니다.

 


1. openCV에서의 산술 연산

산술연산은 그저 더하기 빼기이니 빠르게 코드 설명부터 들어가겠습니다.

그리고 이번 강의에서는 두개의 이미지 크기가 같다는 전제 하에 가능한 코드입니다. 두 이미지 크기가 다르다면, 조금 더 작업이 필요합니다.

 

img1 = cv2.imread('lenna.png')
img2 = cv2.imread('peppers.png')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

이미지끼리의 산술 연산이니 두개의 이미지를 불러와 줍니다. 굳이 그레이 스케일(흑백)일 필요는 없지만 빠르게 진행하기 위해서 그레이 스케일로 진행하겠습니다.

 

height, width = gray1.shape

openCV에서 지원하는 함수로 계산해도 되지만, 중첩 for문으로 계산하기 위해 크기를 저장합니다.

 

plus = gray1.copy()
minus = gray1.copy()
alpha = gray1.copy()

이제 출력을 위한 이미지를 만들어줍니다.

 

for i in range(width):
    for j in range(height):
        plus[i][j] = gray1[i][j] + gray2[i][j]
        minus[i][j] = gray1[i][j] - gray2[i][j]
        alpha[i][j] = gray1[i][j] * 0.5 + gray2[i][j] * (1 - 0.5)
        if plus[i][j] > 255:
            plus[i][j] = 255
        if minus[i][j] < 0:
            minus[i][j] = 0
        if alpha[i][j] > 255:
            alpha[i][j] = 255

이제 중첩 for문을 통해 연산을 하도록 하겠습니다. 더하기 빼기는 말 그대로 더하기 빼기만 해주면 됩니다. 하지만 알파연산은 가중치를 주어야 하기 때문에, 각 이미지에 가중치를 곱해서 더해줍니다. 저는 둘 다 0.5씩 곱해서 진행하겠습니다.

그리고 덧셈 연산과 알파 연산은 더하기이기 때문에 255를 넘는 오버플로우가 발생 할 수 있어서 255가 넘으면 255로 바꾸어주는 오버플로우 방지를, 뺄셈연산은 0의 밑으로 내려가는 언더플로우가 발생 할 수 있어서 0 밑으로 내려가면 0으로 바꾸어주는 언더플로우 방지를 해줍니다.

 

이제 끝났습니다. 이번에는 그저 더하기 빼기이기 때문에 히스토그램은 따로 그릴 필요가 없습니다.

 

이제 완성된 결과를 보겠습니다.

 

원본 이미지1
원본 이미지2
덧셈 연산
뺄셈 연산
알파 연산

 

결과를 보면, 덧셈 연산과 뺄셈 연산은 비슷하지만 약간씩 차이가 있고, 알파 연산은 덧셈 연산과 큰 차이가 있습니다.

덧셈 연산과 뺄셈 연산은 연산 방식은 다르지만, 아무런 조치 없이 더하고 빼서 검은색(0)이나 흰색(255)값이 많이 나오는 편입니다. 그래서 무엇을 더하고 뺐는지가 알기 어렵습니다.

알파 연산은 두 이미지의 절반씩만 더했기에, 두 이미지의 형상이 잘 보이는 특징이 있습니다. 이를 잘 조정해서 가중치가 큰 이미지는 더 선명하게 보이고, 가중치가 더 작은 이미지는 약하게 보이게 해서, 워터마크같은걸 넣어줄 수도 있습니다.


2. 마치며

이번 강의는 매우 짧은 편입니다. 추가로 나온 내용도 없이 그저 더하고 빼기만 하면 됬으니까요.

 

 

import cv2


img1 = cv2.imread('lenna.png')
img2 = cv2.imread('peppers.png')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
height, width = gray1.shape
plus = gray1.copy()
minus = gray1.copy()
alpha = gray1.copy()
for i in range(width):
    for j in range(height):
        plus[i][j] = gray1[i][j] + gray2[i][j]
        minus[i][j] = gray1[i][j] - gray2[i][j]
        alpha[i][j] = gray1[i][j] * 0.5 + gray2[i][j] * (1 - 0.5)
        if plus[i][j] > 255:
            plus[i][j] = 255
        if minus[i][j] < 0:
            minus[i][j] = 0
        if alpha[i][j] > 255:
            alpha[i][j] = 255

cv2.imshow("original1", gray1)
cv2.imshow("original2", gray2)
cv2.imshow('plus', plus)
cv2.imshow('minus', minus)
cv2.imshow('alpha', alpha)

cv2.waitKey(0)
반응형