1. 트랙바
cv2.createTrackbar(trackbarName, windowName, value, count, onChange)
trackbarName | 트랙바 이름 |
windowName | 트랙바를 포함하는 윈도우 이름 |
value | 트랙바 초기값 |
count | 트랙바 최댓값(defalut = 0) |
onChange | 트랙바 값이 변경될떄마다 호출할 콜백 함수 이름 콜백 함수는 아래처럼 사용됨 onChange(pose) |
* 트랙바를 이용한 grayscale 조절 *
import cv2
import numpy as np
def level_change(pos):
value = pos * 8
if value >= 255:
value = 255
img[:] = value
cv2.imshow('img', img)
img = np.zeros((480, 640), dtype=np.uint8)
cv2.namedWindow('img')
cv2.createTrackbar('level', 'img', 0, 32, level_change)
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
* 트랙바를 이용히여 B,G,R 컬러를 각각 조절할 수 있는 프로그램 *
# trackbar_RGB_controller.py
# R,G,B 가 모두 있는 트랙바
import numpy as np
import cv2
def nothing(x):
pass
frame = np.zeros((512, 512, 3), np.uint8)
cv2. namedWindow('frame')
cv2.createTrackbar('R', 'frame', 0, 255, nothing)
cv2.createTrackbar('G', 'frame', 0, 255, nothing)
cv2.createTrackbar('B', 'frame', 0, 255, nothing)
while True:
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == 27:
break
r = cv2.getTrackbarPos('R', 'frame')
g = cv2.getTrackbarPos('G', 'frame')
b = cv2.getTrackbarPos('B', 'frame')
frame[:] = [b, g, r]
cv2.destroyAllWindows()
2. 영상 산술연산
grayscale 인 경우 특정값을 더하거나 빼서 밝기 조절이 가능합니다.
영상의 밝기 조절은 모든 픽셀의 값을 더하거나 빼서 가능합니다.
• 단, 최솟값 0, 최댓값 255로 제한되어 있음
cv2.add(src1, src2, dst=None, mask=None, dtype=None)
• src1 : 첫 번째 입력 영상
• src2 : 두 번째 입력 영상
• dst : 출력 영상 결과
• mask : 마스크 영상
• dtype : 출력 영상(dst) 의 데이터 타입
예) cv2.CV_8U, cv2.CV_32F 등
import cv2
import numpy as np
x = np.uint8([250]) # 250 + 10 = 260 => 255
y = np.uint8([10]) # 250 + 10 = 260 => 260 % 256 = 4
print(cv2.add(x, y))
print(x+y)
위 코드의 실행결과는 255 와 4입니다.
opencv 의 경우 데이터 타입의 범위를 벗어나면 데이터 타입이 갖을 수 있는 최대값이 됩니다.
위 메서드를 컬러 영상에 적용한 간단한 예제입니다.
import os
import cv2
path = os.path.join('my_images', '고양이.jpg')
src = cv2.imread(path)
dst = cv2.add(src, 100)
dst2 = cv2.add(src, (100, 100, 100, 0))
src = cv2.resize(src, dsize=(480, 320), interpolation=cv2.INTER_AREA)
dst = cv2.resize(dst, dsize=(480, 320), interpolation=cv2.INTER_AREA)
dst2 = cv2.resize(dst2, dsize=(480, 320), interpolation=cv2.INTER_AREA)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.imshow('dst2', dst2)
cv2.moveWindow('src', 200, 200)
cv2.moveWindow('dst', 650, 200)
cv2.moveWindow('dst2', 1150, 200)
cv2.waitKey()
cv2.destroyAllWindows()
2.1 임의의 영상과 (직접 만든) src2 영상 를 활용하여 두 영상의 add,substract, weighted sum, abs diff 결과를 하나의 창에 나타내는 프로그램 구현하기
* 결과 *
2-1) cv2.subtract(src1, src2, dst=None, mask=None, dtype=None)
2-2) cv2.addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None)
alpha: src1 에 부여되는 가중치
beta: src2 에 부여되는 가중치
gamma: 영상에 공통적으로 더하는 값
dst: 출력 영상 결과
dtype: 출력 영상 타입
addWeighted 메서드는 알파 블렌딩이라 하며 메서드의 구현 수식은
dst(x,y) = t x src1(x,y) + (1-t) x src2(x,y) (x 는 곱하기를 의미)
입니다.
2-3) cv2.absdiff(src1, src2, dst=None)
- 두 영상의 같은 위치에 있는 픽셀값의 차이를 출력
- 연속된 영상의 경우 변화가 있는 물체의 결과만 출력
위의 3가지 메서드와 앞에서 배운 add 메서드 4가지를 이용하여 src1, src2 이미지들로 산술 연산을 진행한 결과입니다.
2.1 코드
# opencv_Arithmetic.py
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
path = os.path.join('my_images', '고양이.jpg')
src1 = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
h, w = src1.shape
print(h, w)
src2 = np.ones((h, w), dtype=np.uint8)
cv2.rectangle(src2, (50, 50), (200, 200), 255, -1)
dst1 = cv2.add(src1, src2, dtype=cv2.CV_8U)
dst2 = cv2.subtract(src1, src2, dtype=cv2.CV_8U)
dst3 = cv2.addWeighted(src1, 0.5, src2, 0.5, 0)
dst4 = cv2.absdiff(src1, src2)
fig = plt.figure(figsize=(15, 6))
gs = gridspec.GridSpec(nrows=3, # row 몇 개
ncols=2, # col 몇 개
height_ratios=[2, 2, 2],
width_ratios=[3, 3]
)
plt.subplot(231), plt.axis('off'), plt.imshow(
src1, cmap='gray'), plt.title('src1')
plt.subplot(232), plt.axis('off'), plt.imshow(
src2, cmap='gray'), plt.title('src2')
plt.subplot(233), plt.axis('off'), plt.imshow(
dst1, cmap='gray'), plt.title('dst1')
plt.subplot(234), plt.axis('off'), plt.imshow(
dst2, cmap='gray'), plt.title('dst2')
plt.subplot(235), plt.axis('off'), plt.imshow(
dst3, cmap='gray'), plt.title('dst3')
plt.subplot(236), plt.axis('off'), plt.imshow(
dst4, cmap='gray'), plt.title('dst4')
plt.show()
+) bit 연산 - 픽셀별로 논리연산 후 이진수로 표현
비트연산 예제1
코드
# bitwise_example_1.py
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
path = os.path.join('my_images', '고양이.jpg')
src = cv2.imread(path)
gray = cv2.imread(path, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
_and = cv2.bitwise_and(gray, binary)
_or = cv2.bitwise_or(gray, binary)
_xor = cv2.bitwise_xor(gray, binary)
_not = cv2.bitwise_not(gray)
src = np.concatenate((np.zeros_like(gray), gray, binary,
np.zeros_like(gray)), axis=1)
dst = np.concatenate((_and, _or, _xor, _not), axis=1)
dst = np.concatenate((src, dst), axis=0)
dst = cv2.resize(dst, dsize=(1120, 640), interpolation=cv2.INTER_AREA)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
원본 이미지(src)와 그레이스케일(gray), 이진화(binary)을 선언합니다.
연산 이미지는 그레이스케일 이미지와 127 임곗값을 갖는 이진화 이미지를 사용합니다.
cv2.bitwise(연산 이미지1, 연산 이미지2)를 이용하여 비트 연산을 진행합니다.
논리곱값(bitwise_and), 논리합(bitwise_or), 배타적 논리합(bitwise_xor), 부정(bitwise_not) 등으로 연산이 가능합니다.
논리곱 함수는 두 이미지의 요소별 논리곱을 계산합니다.
연산 이미지1과 연산 이미지2의 값을 비트 단위로 파악하며, 해당 비트에 대해 AND 연산을 진행합니다.
논리합 함수는 두 이미지의 요소별 논리합을 계산합니다.
연산 이미지1과 연산 이미지2의 값을 비트 단위로 파악하며, 해당 비트에 대해 OR 연산을 진행합니다.
배타적 논리합 함수는 두 이미지의 요소별 배타적 논리합을 계산합니다.
연산 이미지1과 연산 이미지2의 값을 비트 단위로 파악하며, 해당 비트에 대해 XOR 연산을 진행합니다.
논리합 함수는 두 이미지의 요소별 논리합을 계산합니다.
연산 이미지1의 값을 비트 단위로 파악하며, 해당 비트에 대해 NOT 연산을 진행합니다.
요소의 값이 각각 198, 255인 이미지를 배타적 논리합 비트 연산을 진행한다면 다음과 같습니다.
198은 1100 0110이 되며, 255는 1111 1111이 됩니다.
XOR 연산은 비트 값이 같으면 0, 다르다면 1이 됩니다.
각 자리수 마다 값을 비교한다면 0011 1001이 됩니다.
이 값을 10진수로 변경한다면, 57이 됩니다.
그러므로, 이미지 요소 값은 57의 값으로 할당됩니다.
연결 함수(np.concatenate)로 이미지들을 연결합니다.
비트연산 예제2
좀 더 비교를 위해 아래 2가지 이미지로 비트 연산을 진행 해보겠습니다.
결과
import cv2
import numpy as np
import matplotlib.pyplot as plt
src1 = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)
h, w = src1.shape
src2 = np.ones((h, w), dtype=np.uint8)
# src2 를 흑백 절반으로 바꾸기
for x in range(int(w/2)):
for y in range(h):
src2[y, x] = 255
cv2.imshow('src1', src1)
cv2.imshow('src2', src2)
bit_and = cv2.bitwise_and(src1, src2)
bit_or = cv2.bitwise_or(src1, src2)
bit_not = cv2.bitwise_not(src1, src2)
bit_xor = cv2.bitwise_xor(src1, src2)
plt.subplot(221), plt.axis('off'), plt.imshow(
bit_and, cmap='gray'), plt.title('blt_and')
plt.subplot(222), plt.axis('off'), plt.imshow(
bit_or, cmap='gray'), plt.title('bit_or')
plt.subplot(223), plt.axis('off'), plt.imshow(
bit_not, cmap='gray'), plt.title('bit_not')
plt.subplot(224), plt.axis('off'), plt.imshow(
bit_xor, cmap='gray'), plt.title('bit_xor')
plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
이것으로 이번 포스팅은 마치겠습니다 :)
https://github.com/JangDaehyuk/opencv_self_study/
* 참고 *
http://www.gisdeveloper.co.kr/?p=6407
https://076923.github.io/posts/Python-opencv-32/
'머신러닝,딥러닝 > opencv' 카테고리의 다른 글
opencv 입문하기 7-2편 HSV, 특정 색상 추출(inRange) (0) | 2020.08.08 |
---|---|
opencv 입문하기 7-1편 histogram stretching, equalization (0) | 2020.08.08 |
opencv 입문하기 5편 마우스 이벤트(2) (0) | 2020.07.26 |
opencv 입문하기 4편 키보드, 마우스 이벤트(1) (0) | 2020.07.25 |
opencv 입문하기 3편 영상생성,추출, 그리기 함수 (0) | 2020.07.21 |