Arithmetic and Bitwise Operations

김성빈·2024년 4월 26일
0

Modern Computer Vision

목록 보기
10/117

제목의 뜻은 번역하면 "산술 및 비트 단위 연산" 으로
이미지의 강도나 값을 더하거나 빼는 연산이다.

그레이스케일 이미지로 이미지를 로드할 예정이다.

앞서 라이브러리를 불러오고 이미지를 출력하는 함수를 만드는것은 이전 글에서 설명돼있으므로 생략하겠다.

Arithmetic Operations

아래는 그레이스케일 이미지와 동일한 차원의 모든 픽셀 값을 100으로 설정하는 행렬을 만드는 코드이다.

흑백 이미지는 0(검은색) ~ 255(흰색) 으로 모든 픽셀의 값이 100인 행렬은 사람눈으로 보았을땐 회색 톤의 이미지가 될것이다.

이 작업(행렬을 만드는 행위)은 이미지를 밝게 하거나 어둡게 하는 것과 같은 이미지 처리나 필터링 작업을 수행할 때 사용된다.

# cv2.imread에서 쉼표 0을 추가하면 이미지가 그레이스케일링된 이미지로 로드됩니다
image = cv2.imread('images/liberty.jpeg', 0)
imshow("Grayscaled Image",image)
print(image)

# 행렬을 만든 다음 100의 눈금을 곱합니다
# 이는 모든 값이 100인 동일한 차원의 이미지를 갖는 행렬을 제공합니다
M = np.ones(image.shape, dtype = "uint8") * 100 

코드를 보면 cv2.imread 할때 인자에 0 이 들어가게 되는데 이것은 그레이스케일을 한다는 의미이고 imshow("Grayscaled Image",image) 를하게 되면 흑백사진이 출력될 것이다.

imshow 아래의 print(image)의 뜻은 "이미지 배열의 내용을 출력하라" 는 뜻이며 그레이스케일 이미지 이므로 각 픽셀의 값이 0~255까지의 값으로 표현될 것이다.

그럼 이제 모든 픽셀의 값이 100인 행렬 M을 print 해보자.

이제 이 두개의 행렬을 이용할 것이다.

  1. 그레이스케일 이미지
  2. 회색 이미지

합치기

두개의 이미지를 합친다고 생각을 하면 어두운 원본 이미지에 비교적 밝은 회색의 이미지를 합치는것이니 더 밝아질 것이다.

그러면 OpenCV를 이용해서 두 이미지를 합쳐보자.

# 이 행렬 M을 이미지에 추가하는 데 사용합니다
# 밝기 증가에 주목하십시오
added = cv2.add(image, M)
imshow("Increasing Brightness", added)

# 이제 우리가 그것을 추가했다면, 무슨 일이 일어날지 보세요
added2 = image + M 
imshow("클리핑에서 간단한 Numpy 추가 결과", added2)

이미지를 합치는 방법은 두가지를 이용해서 비교했는데,

첫번째는 함수사용, 두번째는 그냥 연산

우선 결과부터

cv2.add

연산

함수를 이용해 더한 이미지는 전체적으로 밝아진 반면

바로 더하면 검은 점이 몇개 보이게 된다.

왜냐하면 값은 범위(0~255)만 기억하기 때문이다.

만약 원래 이미지의 픽셀값이 200 이상 정도로 있다면 어떨까?

예를들어 232의 값을 가진 픽셀에 회색(100)을 더하게 됐으니 332라는 값이 되는데 위에 말했듯 범위만 기억한다 했으니 255가 초과된 332는 표현할수없다.

그래서 다시 0으로 돌아가 초과분인 332-255 = 77 의 값을 갖게 되면서 원래 밝았던 것들이 합치게 되면서 오히려 어두워지는 현상이 발생한 것이다.

그래서 이미지를 더하게 될때는 저러한 현상으로 인해 함수를 사용해야 하며,
이러한 현상을 순환 혹은 wrapping 이라고 한다.

"반복 혹은 순환 (Wraparound or wrapping)"

이는 값을 한정된 범위 내에 유지하면서 초과되는 부분이 최소값부터 다시 시작되는 과정을 묘사하는 용어

빼기

두개의 행렬(이미지)를 합쳐봤으니 빼보는것도 해보자.

subtracted = cv2.subtract(image, M)
imshow("Subtracted", subtracted)

subtracted = image - M 
imshow("Subtracted 2", subtracted)

이번에도 함수, 연산 두가지 방식으로 진행을 했다.

함수를 이용한 것은 생각했던것과 동일하게 더 어둡게 이미지가 표현이 됐고, 그냥 감산을 한 것의 이미지는 이미지가 더 밝아졌는데,

그저 감산한 이미지라는것을 알았다면 저 이미지의 어두운 부분은 본래 매우 밝은 부분이라는것을 알수있다.

Bitwise Operations and Masking

Bitwise라는것에 대해 설명하기 전에 우선 실습부터 해보자.

아래는 두개의 이미지를 만드는 코드이다.

square = np.zeros((300, 300), np.uint8)
cv2.rectangle(square, (50, 50), (250, 250), 255, -2)
imshow("square", square)

ellipse = np.zeros((300, 300), np.uint8)
cv2.ellipse(ellipse, (150, 150), (150, 150), 30, 0, 180, 255, -1)
imshow("ellipse", ellipse)

이 두개의 이미지를 이용해서 bitwise operations을 할건데

대학생때 gate연산을 생각하면 되고, 실제로 함수자체도 그렇다.

# 교차하는 위치만 표시합니다
And = cv2.bitwise_and(square, ellipse)
imshow("AND", And)

# 사각형 또는 타원이 있는 위치를 표시합니다
bitwiseOr = cv2.bitwise_or(square, ellipse)
imshow("bitwiseOr", bitwiseOr)

# 둘 중 하나가 존재하는 곳을 자체적으로 보여줍니다
bitwiseXor = cv2.bitwise_xor(square, ellipse)
imshow("bitwiseXor", bitwiseXor)

# 정사각형의 일부가 아닌 모든 것을 보여줍니다
bitwiseNot_sq = cv2.bitwise_not(square)
imshow("bitwiseNot_sq", bitwiseNot_sq)

# 마지막 작업이 이미지를 완전히 반전시킵니다

순서대로 and,or,xor,not을 이용해서 이미지를 표현한다.

imshow("AND", And)

imshow("bitwiseOr", bitwiseOr)

imshow("bitwiseXor", bitwiseXor)

imshow("bitwiseNot_sq", bitwiseNot_sq)

결과를 보면 현재 이것들이 배우는데 있어서 쓸모없어 보일지는 몰라도.

이런 함수들을 사용하고 그때 느끼고 이해한 내용들이 나중에 어려운 문제를 해결해주는 중요한 포인트라 믿는다.

profile
감사합니다. https://www.youtube.com/channel/UCxlkiu9_aWijoD7BannNM7w

0개의 댓글

관련 채용 정보