오늘은 그동안 배웠던 OpenCV의 기능을 최대한으로 활용한 실습 문제를 하나 풀었는데 생각보다 많이 어려웠다. 크게 3가지의 기능을 구현해보는 내용이었는데, 2단계까지는 어떻게 하다 보니 구현했는데 마지막 3단계 구현을 끝내 못했다. 최종적으로 구현된 코드를 계속 보면서 공부를 더 해봐야겠다.
cv2.setMouseCallback(winName, onMouse)onMouse(event) : 마우스 이벤트를 처리하는 콜백 함수, 첫번째 인자로 이벤트를 받아줌# 원본 사용 (누적)
img = cv.imread(DOG_PATH)
name = "Mouse Event"
cv.namedWindow(name)
def on_mouse(event, x, y, flags, _):
if event == cv.EVENT_LBUTTONDOWN:
cv.circle(img, (x,y), 20, (255,255,0), cv.FILLED)
cv.imshow(name, img)
cv.setMouseCallback(name, on_mouse)
cv.imshow(name, img)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
# 복사본 사용 (갱신)
img = cv.imread(DOG_PATH)
name = "Mouse Event"
cv.namedWindow(name)
def on_mouse(event, x, y, flags, _):
if event == cv.EVENT_LBUTTONDOWN:
copied = img.copy()
cv.circle(copied, (x,y), 20, (255,255,0), cv.FILLED)
cv.imshow(name, copied)
cv.setMouseCallback(name, on_mouse)
cv.imshow(name, img)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
# 마우스 이벤트 + 원근 변환
PRACTICE_PATH = "../images/book2.jpg"
img = cv.imread(PRACTICE_PATH)
name = "Mouse Event(Practice)"
point_list = []
def show_result():
width = int(np.linalg.norm(np.array(point_list[0]) - (point_list[1])))
height = int(np.linalg.norm(np.array(point_list[0]) - (point_list[3])))
src = np.array(point_list, dtype=np.float32)
dst = np.array([[0,0], [width,0], [width,height], [0,height]], dtype=np.float32)
mat = cv.getPerspectiveTransform(src, dst)
result = cv.warpPerspective(img, mat, (width, height))
cv.imshow("warped", result)
drawing = False
def on_mouse(event, x, y, flags, _):
global drawing
coppied = img.copy()
point = (x,y)
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
point_list.append(point)
if drawing:
prev_point = None
for p in point_list:
cv.circle(coppied, p, 10, (0,0,255), cv.FILLED)
if prev_point:
cv.line(coppied, prev_point, p, (0,0,255), 5)
prev_point = p
if len(point_list) == 4:
point = point_list[0]
show_result()
cv.line(coppied, point_list[-1], point, (0,0,255), 5)
cv.imshow(name, coppied)
cv.namedWindow(name)
cv.setMouseCallback(name, on_mouse)
cv.imshow(name, img)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
cv2.Canny(img, threshold1, threshold2)threshold1 : 약한 경계 임계값threshold2 : 강한 경계 임계값img = cv.imread(MOUNTAIN_PATH, cv.IMREAD_GRAYSCALE)
canny = cv.Canny(img, 50, 150)
cv.imshow("img", img)
cv.imshow("canny", canny)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread(MOUNTAIN_PATH, cv.IMREAD_GRAYSCALE)
name = "Canny"
cv.namedWindow(name)
cv.createTrackbar("threshold1", name, 50, 255, lambda x:x)
cv.createTrackbar("threshold2", name, 150, 255, lambda x:x)
while True:
threshold1 = cv.getTrackbarPos("threshold1", name)
threshold2 = cv.getTrackbarPos("threshold2", name)
canny = cv.Canny(img, threshold1, threshold2)
cv.imshow(name, canny)
if cv.waitKey(1) == ord("q"):
break
cv.destroyAllWindows()
cv.waitKey(1)
cap = cv.VideoCapture(0)
name = "Canny"
cv.namedWindow(name)
cv.createTrackbar("threshold1", name, 50, 255, lambda x:x)
cv.createTrackbar("threshold2", name, 150, 255, lambda x:x)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
threshold1 = cv.getTrackbarPos("threshold1", name)
threshold2 = cv.getTrackbarPos("threshold2", name)
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
canny = cv.Canny(gray, threshold1, threshold2)
cv.imshow(name, canny)
if cv.waitKey(1) == ord("q"):
break
cap.release()
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread("../images/dog.jpg", cv.IMREAD_GRAYSCALE)
blur = cv.GaussianBlur(img, (5,5), 0)
canny = cv.Canny(img, 50, 150)
canny_blur = cv.Canny(blur, 50, 150)
cv.imshow("img", canny)
cv.imshow("blur", canny_blur)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
img = cv.imread(DOG_PATH)
coppied = img.copy()
# 그레이 스케일로 변환
gray = cv.cvtColor(coppied, cv.COLOR_BGR2GRAY)
# 이진화
ret, binary = cv.threshold(gray, -1, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
# 윤곽선 찾기
contours, hierachy = cv.findContours(binary, cv.RETR_CCOMP, cv.CHAIN_APPROX_NONE)
# 윤곽선 그리기
cv.drawContours(img, contours, -1, (0,255,0), 2)
cv.imshow("Contours", img)
cv.waitKey(0)
cv.destroyAllWindows()
cv.waitKey(1)
조금씩 어려운 내용이 나오기는 하지만 OpenCV 사용이 어느 정도 적응이 된 것 같아서 괜찮게 따라가고 있는 것 같다.