no image
[OpenCV] 이미지의 특정 위치 좌표 추출
OpenCV로 이미지의 원하는 위치의 좌표 추출하는 법을 알아보자 좌표를 추출하여 해당 위치의 이미지 색상을 바꾸는 등의 응용까지 해볼 수 있다. 해당 이미지를 가지고 현재 회색인 신체 윤곽선 부분을 초록색으로 바꿔보자 1. 윤곽선 이미지 불러오기 import cv2 person = cv2.imread('person.png') 검은색 배경에 회식 라인의 윤곽선 이미지다. 2. 이미지 회색 처리 gray = cv2.cvtColor(resized_person, cv2.COLOR_BGR2GRAY) cv2.imshow('result', gray) cv2.waitKey(0) cv2.destroyAllWindows() 해당 이미지의 좌표를 추출하기 위해 이미지 이진화 작업이 꼭 필요한데 그 전에 회색 처리를 먼저 ..
2024.02.21
no image
[OpenCV] 이미지 합성
OpenCV로 이미지 끼리 합성을 하는 방법을 알아보자. 이미지 합성을 하기 위해서는 OpenCV에서 제공하는 비트 연산 기능을 이용하면 된다. 비트 연산 기능을 이용하여 배경 사진에 특정 로고 사진을 합성해보자 1. 로고 이미지 이진화 img_logo = cv2.imread('logo.png') img_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY) # 이진화 전 회색 처리 필수 ret, img_mask = cv2.threshold(img_gray, 200, 255, cv2.THRESH_BINARY) img_mask_inv = cv2.bitwise_not(img_mask) cv2.imshow('img_mask', img_mask) cv2.imshow('img_m..
2024.02.08
no image
[OpenCV] 이미지 윤곽선 검출
사람의 인체 모양을 인식하고 어떠한 판단을 내리기 위해서는 신체에 윤곽선을 그리고, 해당 윤곽선에 대한 좌표 데이터를 획득해야 한다. 이러한 목표를 성취하기 위해서 첫 번째로 해야 할 작업은 이미지 안에 특정 사물의 윤곽선을 그리는 것부터 시작한다. 이 글은 파이썬의 이미지 처리 라이브러리인 OpenCV를 통해서 이미지 내 윤곽선을 검출하는 방법을 기술한다. 앞서 작성한 OpenCV의 설명을 보자면 OpenCV는 이미지를 흑백으로 변경을 하거나 이미지의 특정 위치의 좌표값을 얻는 등 여러 처리를 할 수 있는 라이브러리다. 해당 라이브러리를 사용하여 윤곽선을 검출하기 위해 과정을 단계별로 나누자면 이미지의 윤곽선을 검출하는 과정 이미지 회색 처리 이미지 바이너리 처리 위 모든 과정을 거친 이미지의 윤곽선 ..
2024.02.07
[OpenCV] OpenCV 미니 창에 마우스 이벤트 처리하기
OpenCV의 기본적인 기능에는 이미지를 처리하기 위해 해당 이미지를 표시하는 창을 띄운다. 더불어, 해당 창을 특별한 기능이 담긴 프로젝트로 제작하기 위해 마우스 이벤트를 처리하는 기능을 제공하고 있다. 1. 마우스 이벤트 핸들러 함수 정의 - 마우스의 이벤트에 따라 원하는 동작을 수행하도록 하는 말그대로 이벤트 핸들러 함수를 정의한다. import cv2 def mouse_event(event, x, y, flags, param) : if event == cv2.EVENT_LBUTTONDOWN: print('왼쪽 마우스 클릭') elif event == cv2.EVENT_LBUTTONUP: print('왼쪽 마우스 클릭 해제 ') elif event == cv2.EVENT_LBUTTONDBLCLK: ..
2023.12.30
no image
[OpenCV] OpenCV를 이용하여 동영상 출력
OpenCV (Computer Vision)란? - 다양한 영상 (이미지) / 동영상 처리에 사용되는 오픈소스 라이브러리 => ex) 이미지를 흑백으로 변경, 이미지의 특정 영역을 잘라내기 - OpenCV의 기능을 이용하여 여러 응용 프로젝트를 제작할 수 있다 => ex) 문서 스캐너, 얼굴 인식, 모션 인식 1. OpenCV 설치 - 파이썬을 실행하는 에디터에 맞는 프롬프트에서 해당 명령어를 입력한다. (Jupyter Notebook: Anaconda Prompt, PyCharm: 에디터 터미널) 2. OpenCV 라이브러리 Import - OpenCV를 설치 했으면 파이썬 코드 내에서 cv2라는 이름으로 OpenCV를 임포트 할 수 있다. import cv2 3. 동영상 파일 읽어오기 1) cv2.V..
2023.12.19
728x90

OpenCV로 이미지의 원하는 위치의 좌표 추출하는 법을 알아보자

좌표를 추출하여 해당 위치의 이미지 색상을 바꾸는 등의 응용까지 해볼 수 있다.

해당 이미지를 가지고 현재 회색인 신체 윤곽선 부분을 초록색으로 바꿔보자

 

1. 윤곽선 이미지 불러오기

import cv2

person = cv2.imread('person.png')
  • 검은색 배경에 회식 라인의 윤곽선 이미지다.

 

 

2. 이미지 회색 처리

gray = cv2.cvtColor(resized_person, cv2.COLOR_BGR2GRAY)

cv2.imshow('result', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 해당 이미지의 좌표를 추출하기 위해 이미지 이진화 작업이 꼭 필요한데 그 전에 회색 처리를 먼저 확실하게 해준다.

 

 

3. 이미지 이진화

ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

cv2.imshow('result', otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 오츠 알고리즘을 통해 자동으로 이미지 이진화를 진행한다.

  • 좌표 추출을 원하는 위치가 검정색(픽셀 값: 0)이 되어야 한다. cv2.bitwise_not(otsu) 를 실행하여 반전 이진화를 진행한다.

 

 

4. 해당 윤곽선 좌표 추출

import numpy as np
np.where(contour == 0)
  • np.where() 는 Numpy 자료형 array 에 특정 조건을 만족하는 위치의 인덱스를 가져올 수가 있다.

  • 이미지를 OpenCV로 불러오게 되면 Numpy 자료형으로 불러오게 된다.

 

 

5. 회색 이미지에서 컬러 이미지로 변환

contour_color = cv2.cvtColor(contour, cv2.COLOR_GRAY2BGR)
  • 이미지를 가지고 회색 처리나 이진화를 하게 되면 색상 값이 하나만 존재하게 된다.
  • 이미지는 Numpy 자료형이기 때문에 배열로 치자면 컬러는 R,G,B 3가지의 색상 값을 가지고 있기 때문에 3차원 배열이고, 무채색 이미지는 검은색 계열 한가지의 색상만 존재하기 때문에 2차원 배열이다.

  • 따라서, 컬러 이미지로 변환을 해주면 2차원에서 3차원으로 변환된다.

  • 이미지의 검색 부분을 초록색으로 변경해줄 것이기 때문에 이와 같이 컬러 이미지로 변환한다.

 

 

6. 이미지 내 검정색 부분 초록색으로 변환

contour_color[np.where(contour == 0)] = [0,255,0] 
# 검은색=[0,0,0] 초록색=[0,255,0]
  • np.where(contour==0) 를 통해 윤곽선 이미지의 검은색 부분을 찾는다.
  • contour_color[np.where(contour == 0)] = [0,255,0] 컬러로 변환된 이미지에 찾은 좌표를 매칭시켜 초록색 RGB값을 삽입한다.

※ 결과

728x90

[OpenCV] 이미지 합성

태이니즘
|2024. 2. 8. 18:04
728x90

OpenCV로 이미지 끼리 합성을 하는 방법을 알아보자.

이미지 합성을 하기 위해서는 OpenCV에서 제공하는 비트 연산 기능을 이용하면 된다.

비트 연산 기능을 이용하여 배경 사진에 특정 로고 사진을 합성해보자

배경 이미지
로고 이미지

 

 

1. 로고 이미지 이진화

img_logo = cv2.imread('logo.png')
img_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY) # 이진화 전 회색 처리 필수
ret, img_mask = cv2.threshold(img_gray, 200, 255, cv2.THRESH_BINARY)
img_mask_inv = cv2.bitwise_not(img_mask)
cv2.imshow('img_mask', img_mask)
cv2.imshow('img_mask_inv', img_mask_inv)
cv2.waitKey()
cv2.destroyAllWindows()
  • cv.threshold(img_gray, 200, 255, cv.THRESH_BINARY)를 사용하여 이진화를 진행한다. 해당 코드를 보면 픽셀이 200을 넘는 부분은 흰색인 배경만 존재하기 때문에 배경을 제외하고는 검은색으로 변환 될 것이다. *** 흰색 픽셀: 255, 검정색 픽셀: 0**
  • img_mask_inv = cv2.bitwise_not(img_mask) 는 위 바이너리 이미지를 반전 시키는 코드이다. 해당 이미지도 이미지 합성 시에 꼭 필요하다.

 

 

2. 로고 이미지 크기로 배경 이미지 잘라내기

img_background = cv2.imread('background.png')
height, width = img_logo.shape[:2]
img_roi = img_background[0:height, 0:width]
cv2.imshow('imgroi', img_roi)
cv2.waitKey()
cv2.destroyAllWindows()
  • 로고 이미지를 배경 이미지의 원하는 위치에 삽입을 하려면 해당 부분의 로고 이미지 크기 만큼 잘라낸다.
  • 잘라낸 배경 이미지에 로고 이미지와 비트 연산을 진행해야 한다.

 

 

3. 로고 이미지와 배경 이미지 합성 연산

img1 = cv2.bitwise_and(img_logo, img_logo, mask = img_mask_inv) 
img2 = cv2.bitwise_and(img_roi, img_roi, mask=img_mask)
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.waitKey()
cv2.destroyAllWindows()
  • cv2.bitwise_and(img_logo, img_logo, mask = img_mask_inv) 를 통해 로고 이미지 및 배경 이미지와 앞서 이진화를 진행한 바이너리 이미지와 AND 연산한다.

합성할 로고 이미지
합설할 배경 이미지

  • 위 AND 연산 결과로 나온 로고 이미지(img1)와 배경 이미지(img2) 자체를 더한다.
dst = cv2.add(img1, img2)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

 

 

4. 합성이 완료된 이미지 원본 이미지에 덮어 씌우기

img_background[0:height, 0:width] = dst
cv2.imshow('result', img_background)
cv2.waitKey()
cv2.destroyAllWindows()
  • 합성이 완료된 이미지 부분을 원본 이미지의 부분과 일치 시켜 덮어 씌운다.

※ 결과

728x90
728x90

사람의 인체 모양을 인식하고 어떠한 판단을 내리기 위해서는 신체에 윤곽선을 그리고, 해당 윤곽선에 대한 좌표 데이터를 획득해야 한다.

 

이러한 목표를 성취하기 위해서 첫 번째로 해야 할 작업은 이미지 안에 특정 사물의 윤곽선을 그리는 것부터 시작한다.

 

이 글은 파이썬의 이미지 처리 라이브러리인 OpenCV를 통해서 이미지 내 윤곽선을 검출하는 방법을 기술한다.

 

앞서 작성한 OpenCV의 설명을 보자면 OpenCV는 이미지를 흑백으로 변경을 하거나 이미지의 특정 위치의 좌표값을 얻는 등 여러 처리를 할 수 있는 라이브러리다.

 

해당 라이브러리를 사용하여 윤곽선을 검출하기 위해 과정을 단계별로 나누자면

  • 이미지의 윤곽선을 검출하는 과정
    1. 이미지 회색 처리
    2. 이미지 바이너리 처리
    3. 위 모든 과정을 거친 이미지의 윤곽선 검출
    4. 해당 윤곽선 이미지에 그리기

위와 같은 단계를 거친다.

 

1. 이미지 회색 처리

img = cv2.imread('card.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  • cv2.cvtColor() 는 이미지를 특정 색상으로 변환해준다.
  • 첫 번째 파라미터로 이미지를 삽입하고 두 번째 파라미터로 색상 변환 방법을 삽입한다.
  • cv2.COLOR_BGR2GRAY 는 기존 BGR 방식의 색상에서 회색계열로 이미지를 변환한다는 의미이다.

 

 

2. 이미지 바이너리 처리

ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
  • 이미지를 바이너리(이진화) 시키면 픽셀 값은 0과 255만 갖게 할 수 있기 때문에 흰색과 검은색만 존재하게 할 수 있다.
  • 흰색과 검은색만 이루어진 이미지를 윤곽선 검출하기가 수월하기 때문에 이 과정을 꼭 거쳐야 한다.
  • cv2.threshold() 함수는 여러 개의 숫자 값을 특정한 임계값을 기준으로 두 가지 값으로 나누어 정의하는 함수이다.
  • cv2.threshold(image, threshold, value, type_flag)

      => image: 변환할 이미지, 이미지가 픽셀 값으로 변환되어 들어간다.

      => threshold: 임계값, 우리는 해당 임계값을 오츠 알고리즘이라는 것을 이용하여 자동으로 탐색할 것이기 때문에

            -1을 넣어주면 된다.

      => value: threshold에 기입한 임계값의 특정 조건에 만족하면 변환할 값

      => type_flag: 이진화 적용 방법, cv2.THRESH_BINARY는 픽셀 값이 임계값을 넘으면 value로 지정하고,

           넘지 못하면 0으로 지정하는 방법이다.

           해당 파라미터로 OR 조건으로 cv2.THRESH_OTSU 도 함께 기입할 시 오츠 알고리즘이 적용된다.

  • 오츠 알고리즘이란?

      => 이미지의 픽셀을 보고 이미지의 색상이 두 부류로 나뉘었을 때

            그림의 명암 분포가 가장 균일할 때의 임계값을 자동으로 계산하여 선택하는 알고리즘이다.

 

 

3. 위 모든 과정을 거친 이미지의 윤곽선 검출

contours, hierarchy = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
  • 앞서 변환한 바이너리 이미지에 대해 윤곽선을 검출한다.
  • contours 에 검출한 윤곽선의 좌표값들이 들어가기에, 윤곽선에 대한 작업 진행 시 이 변수를 적극 활용하면 된다.
  • cv2.findContours(image, mode, method)

      => image: 입력 이미지

      => mode: 윤곽선 검출 모드

        - cv2.RETR_EXTERNAL : 가장 외곽의 윤곽선만 찾음

        - cv2.PETR_LIST : 모든 윤곽선 찾음

      => method: 윤곽선 좌표값 반환 방법

        - APPROX_NONE: 윤곽선의 모든 좌표를 반환

        - APPROX_SIMPLE: 윤곽선의 꼭짓점 좌표만 반환

        - 윤곽선이 단순한 경우, 예를 들어 사각형인 경우에는 APPROX_SIMPLE을 사용하는 것이 메모리 성능에도

          효율적일 것이다.

 

 

4. 해당 윤곽선 이미지에 그리기

COLOR = (0, 200, 0) # 녹색
cv2.drawContours(img, contours, -1, COLOR, 2)
# cv2.drawContours(이미지, 윤곽선 정보, 인덱스, 색상, 두께)
# 인덱스가 -1이면 전체
  • 초록색에 두께 2로 전체 윤곽선을 이미지에 그린다.

 

※ 결과

728x90
728x90

OpenCV의 기본적인 기능에는 이미지를 처리하기 위해 해당 이미지를 표시하는 창을 띄운다.

 

더불어, 해당 창을 특별한 기능이 담긴 프로젝트로 제작하기 위해 마우스 이벤트를 처리하는 기능을 제공하고 있다.

 

1. 마우스 이벤트 핸들러 함수 정의

  - 마우스의 이벤트에 따라 원하는 동작을 수행하도록 하는 말그대로 이벤트 핸들러 함수를 정의한다. 

import cv2

def mouse_event(event, x, y, flags, param) :
    if event == cv2.EVENT_LBUTTONDOWN:
        print('왼쪽 마우스 클릭')
    elif event == cv2.EVENT_LBUTTONUP:
        print('왼쪽 마우스 클릭 해제 ')
    elif event == cv2.EVENT_LBUTTONDBLCLK:
        print('왼쪽 마우스 더블 클릭')
    elif event == cv2.EVENT_MOUSEMOVE:
        print('마우스 이동')
    elif event == cv2.EVENT_RBUTTONDOWN:
        print('오른쪽 버튼 클릭')

  - 이벤트 핸들러 내의 함수는 5개의 파라미터를 받을 수 있다. 주로 사용하는 것은 아래 3가지다.

    1) event: 창 내에서 발생하는 마우스 이벤트 자체

    2) x: 이벤트가 발생한 마우스의 X좌표

    3) y: 이벤트가 발생한 마우스의 Y좌표

  - 마우스의 동작에 따라 각 이벤트 변수가 아래와 같이 지정되어 있다.

cv2.EVENT_LBUTTONDOWN #왼쪽 마우스 클릭
cv2.EVENT_LBUTTONUP #왼쪽 마우스 클릭 해제 
cv2.EVENT_LBUTTONDBLCLK #왼쪽 마우스 더블 클릭
cv2.EVENT_MOUSEMOVE #마우스 이동
cv2.EVENT_RBUTTONDOWN #오른쪽 버튼 클릭

 

2. 이미지 창 출력 및 해당 창에 이벤트 핸들러 적용

  - 위에 정의한 이벤트 핸들러 함수를 이미지 창에 적용해보자.

img = cv2.imread('dog.jpg')
cv2.namedWindow('dog')
cv2.setMouseCallback('dog', mouse_event)
cv2.imshow('dog', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

  - 해당 코드 내 중요한 부분은 2가지다.

    1) cv2.namedWindow('dog'): 'dog' 라는 타이틀의 이미지 창을 생성한다.

    2) cv2.setMouseCallback('dog', mouse_event): 앞서 생성한 'dog' 라는 이미지 창에

        위에서 정의한 핸들러 함수를 적용시킨다.

728x90
728x90

OpenCV (Computer Vision)란?

  - 다양한 영상 (이미지) / 동영상 처리에 사용되는 오픈소스 라이브러리

    => ex) 이미지를 흑백으로 변경, 이미지의 특정 영역을 잘라내기

  - OpenCV의 기능을 이용하여 여러 응용 프로젝트를 제작할 수 있다

    => ex) 문서 스캐너, 얼굴 인식, 모션 인식

 

1. OpenCV 설치

  - 파이썬을 실행하는 에디터에 맞는 프롬프트에서 해당 명령어를 입력한다. (Jupyter Notebook: Anaconda Prompt, PyCharm: 에디터 터미널)

 

2. OpenCV 라이브러리 Import

  - OpenCV를 설치 했으면 파이썬 코드 내에서 cv2라는 이름으로 OpenCV를 임포트 할 수 있다.

import cv2

 

3. 동영상 파일 읽어오기

  1) cv2.VideoCapture() 함수를 사용하여 읽어올 수 있다.

  2) 읽어온 영상 자체를 cap이라는 변수에 저장한다.

cap = cv2.VideoCapture('video.mp4')

  

4. 동영상 출력

  1) cap.isOpened() 함수를 사용하여 동영상 파일 업로드 성공 여부를 판단하여 반복문을 시작한다.

    => 동영상을 출력하기 위해 영상 내 프레임 단위의 이미지를 순차적으로 출력해야 하므로 반복문을 사용한다.

  2) cap.read() 함수를 사용하여 영상의 프레임 존재 여부와 프레임 자체를 가져온다.

  3) cv2.imshow() 함수 내 프레임을 삽입하여 해당 프레임 이미지를 출력한다.

  - 위 3단계가 프레임이 존재하지 않을 때까지 반복되어 연속된 프레임을 출력, 결국 영상이 출력된다.

while cap.isOpened(): # 동영상 파일이 올바르게 열렸는지?
    ret, frame = cap.read() # ret: 프레임 존재 여부, frame: 받아온 이미지 (프레임)
    if not ret:
        print('더 이상 가져올 프레임이 없어요')
        break
        
    cv2.imshow('video', frame) # 'video' 라는 이름의 창에 영상이 출력된다

 

5. 동영상 종료

   - 영상이 종료되었으므로 영상을 재생하는 메모리를 해제하여 자원을 반납하고, 해당 영상 창을 닫는다.

cap.release() #자원 해제
cv2.destroyAllWindows()

 

※ 전체 코드

import cv2
cap = cv2.VideoCapture('video.mp4')

while cap.isOpened(): # 동영상 파일이 올바르게 열렸는지?
    ret, frame = cap.read() # ret: 성공 여부, frame: 받아온 이미지 (프레임)
    if not ret:
        print('더 이상 가져올 프레임이 없어요')
        break
        
    cv2.imshow('video', frame)
        
cap.release() #자원 해제
cv2.destroyAllWindows()
728x90