이미지 형태, 비디오 형태의 분석을 위한 기초 분석 

 

1. cv2.calcHist(images, channels, mask, histSize, ranges)

  • images : 분석 대상 이미지 (uint8 or float32) 
  • channels : 분석 채널 grayscale은 [0], color는 [0],[0,1] : 1 Blue 2:Green 3: Red
  • mask : 이미지의 분석 영역, None 은 전체 영역 
  • histSIze : 분석 값 x축의 간격 하나의 
  • range : x 축 범위  
import cv2
import os 
import numpy as np
from matplotlib import pyplot as plt

image = cv2.imread('test.jpg', cv2.IMREAD_COLOR)
image = cv2.resize(image, (512,512))
# image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 0 : Blue, 1: Green, 2: Red
blue_hist = cv2.calcHist([image],[0],None,[256],[0,256])
green_hist = cv2.calcHist([image],[1],None,[256],[0,256])
red_hist = cv2.calcHist([image],[2],None,[256],[0,256])

plt.subplot(111), 
plt.plot(blue_hist , color='b'), 
plt.plot(green_hist, color='g'), 
plt.plot(red_hist, color='r'),

cv2.imshow('test',image)

plt.xlim([0,256])

plt.show()

 

  • 위의 코드에서 주석처리된 부분에 cvt color 부분을 주석 처리한 이유는 opencv는 기본적으로 모든 색상 순서가 BGR로 되어있다. 그래서 변환 없이 바로 imshow로 보여주면 bgr을 bgr로 보여주기 때문에 cv2.imshow를 할 때는 ctvCOLOR를 이용할 이유가 없다. 하지만 plt.imshow()의 경우는 ctvCOLOR를 이용하여 보여줘야 원래 이미지대로 볼 수 있다. 

    같은 이미지이지만 왼쪽은 cv2.imshow()이고 오른쪽은 plt.imshow()이다 
  • 왼쪽은 cv2.imshow()를 한 이미지, 오른쪽은 plt.imshow()를 한 이미지 
  • cv2.imshow는 BGR로 불러와 내보낼 때도 BGR로 내보내지만 cv2로 읽어온 객체를 plt로 내보내면 RGB 순서로 돼있
  • 다는 가정하에 읽어오기 때문에 파란 이미지가 빨간색으로 표현된다 


    BGR과 RGB가 햇갈려서 테스트를 통해 확인하였다
  • cv2.calcHist의 2번째 파라미터는 0: blue, 1:green, 2:red 이다 
  • 각각 히스토그램의 shape를 찍어본 이유는 cv2.calcHist의 return value를 확인하기 위해서다. 각 1차원의 결괏값을 가진다 

  • 다음과 같이 hist의 return 값은 x와 y 축의 2차원 배열이다 shape은 (256,1) 로써 첫 차원에는 0~ 255까지의 pixel의 개수가 포함되어 있다
  • 왼쪽 사진은 위의 파란 이미지의 BGR 히스토그램 return값을 print 한것이다 
    Blue는 255 색상뿐이여서 0, 0, 0이라 나왔고 
    green과 red는 0 색상뿐이여서 배열의 첫 번째인 0 값이 해당 이미지의 넓이만큼 나왔다 ( 512x 512 = 262144 ) = blue는 모두 255이고 green, red는 모두 0이다라는 뜻 

2. calcHist mask 

  • calcHist에 파라미터인 mask를 추가하여 특정 영역의 히스토그램을 추출할 수 있다 
  • 차량의 레이블을 생성하여 읽어와 해당 레이블 영역의 히스토그램을 추출하여 보겠다 
    # print(image.dtype) : uint8
    mask = np.zeros(image.shape[:2], np.uint8)
    mask[box_ymin:box_ymax, box_xmin:box_xmax ] = 255
    
    mask_image = image[box_ymin:box_ymax, box_xmin:box_xmax]
    
    blue_hist = cv2.calcHist([image],[0],mask,[256],[0,256])
    green_hist = cv2.calcHist([image],[1],mask,[256],[0,256])
    red_hist = cv2.calcHist([image],[2],mask,[256],[0,256])
    
    plt.subplot(221),plt.imshow(image)
    plt.subplot(222),plt.imshow(testtestest)
    plt.subplot(223),plt.imshow(mask_image)
    plt.subplot(224), plt.plot(blue_hist, color='b'),plt.plot(green_hist, color='g'),plt.plot(red_hist, color='r')
    plt.xlim([-10,266])
    
    plt.show()​

  • 기존의 calcHist 함수에 None으로 돼있던 위치에 mask 값을 추가하였다 
  • mask 는 해당 이미지에서 추출할 영역을 선택한다 
  • 중요한 점은 cv2.imread()로 읽어온 이미지는 uint8형 자료이기 때문에 mask를 적용할 때 mask의 값 또한 uint8로 맞춰줘야 한다 그렇기 때문에 mask = np.zeros()를 할 때 dtype=np.uint8로 지정하였다 

 

소스코드https://github.com/dldidfh/tistory_code/blob/master/%ED%9E%88%EC%8A%A4%ED%86%A0%EA%B7%B8%EB%9E%A8/histogram_opencv.py

 

GitHub - dldidfh/tistory_code

Contribute to dldidfh/tistory_code development by creating an account on GitHub.

github.com

 

+ Recent posts