CCTV속에 찍힌 사람 감지





인사동 거리에서 찍힌 사람들 감지



import cv2


#괄호안에 파일명을 쓰면 파일이 로드됌

cap = cv2.VideoCapture('test_human1.mp4') #비디오 파일 불러오기

font = cv2.FONT_HERSHEY_SIMPLEX #사람 감지 글씨체 정의



#create the window & change the window size

#윈도우 생성 및 사이즈 변경

cv2.namedWindow('Face')


#지난번엔 frontal_face 이번엔 fullbody

face_cascade = cv2.CascadeClassifier('haarcascade_fullbody.xml')


while(True):

    #read the camera image

    #카메라에서 이미지 얻기

    ret, frame = cap.read()


    grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    


    faces = face_cascade.detectMultiScale(grayframe, 1.8, 2, 0, (30, 30))


    for (x,y,w,h) in faces:

        cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),3, 4, 0)

        cv2.putText(frame, 'Detected human', (x-5, y-5), font, 0.9, (255,255,0),2)


    cv2.imshow('Face',frame)


    #wait keyboard input until 10ms

    #300ms 동안 키입력 대기

    #키를 누르면 꺼진다. 사진의 형태에서 얼굴 감지

    """if cv2.waitKey(300) >= 0:

break"""


#영상의 형태에서 얼굴 감지, space 입력시 중지

    if cv2.waitKey(1) != 255:

        break;


#close the window

#윈도우 종료

cap.release()

cv2.destroyWindow('Face')





지난번 시간이랑은 달리 X,Y data가 matrix로 되어있다.





multi - variable에 따른 hypothesis, cost




지난번 시간에 H(x) = W*x + b였다면, multi-variable 에서는 H(x)=X*W이다. (X,W는 행렬의 형태)




# Lab 4 Multi-variable linear regression

import tensorflow as tf

tf.set_random_seed(777)  # for reproducibility


# 5행 3열의 X_data, 1열의 Y_data

x1_data = [73., 93., 89., 96., 73.]

x2_data = [80., 88., 91., 98., 66.]

x3_data = [75., 93., 90., 100., 70.]


y_data = [152., 185., 180., 196., 142.]


# placeholders for a tensor that will be always fed.

# X,Y의 노드를 생성시킨다.

x1 = tf.placeholder(tf.float32)

x2 = tf.placeholder(tf.float32)

x3 = tf.placeholder(tf.float32)


Y = tf.placeholder(tf.float32)


#hypothesis 함수를 만족시키기 위한 w,b값을 랜덤으로 설정한다. 

w1 = tf.Variable(tf.random_normal([1]), name='weight1')

w2 = tf.Variable(tf.random_normal([1]), name='weight2')

w3 = tf.Variable(tf.random_normal([1]), name='weight3')

b = tf.Variable(tf.random_normal([1]), name='bias')


hypothesis = x1 * w1 + x2 * w2 + x3 * w3 + b


# cost function

# 비용함수 정의

cost = tf.reduce_mean(tf.square(hypothesis - Y))


# Minimize. Need a very small learning rate for this data set

# 경사하강법을 이용한 비용함수의 최소화 과정

optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-2)

train = optimizer.minimize(cost)


# Launch the graph in a session.

sess = tf.Session()

# Initializes global variables in the graph.

sess.run(tf.global_variables_initializer())


# cost, hypothesis, train에 대해서 running을 한다. 

# x,y node에 x,y data를 삽입.

for step in range(2001):

    cost_val, hy_val, _ = sess.run([cost, hypothesis, train],

                                   feed_dict={x1: x1_data, x2: x2_data, x3: x3_data, Y: y_data})


# 10스텝씩 진행함.

# step, cost값,prediction값 = hypothesis 출력

    if step % 10 == 0:

        print(step, "Cost: ", cost_val, "\nPrediction:\n", hy_val)


저번시간엔 X, Y그래프를 봤다면 이번엔 W, cost 그래프이다.

W가 random으로 어느 값을 갖든 W -> 1로 수렴한다는 내용이다.

수렴하는 원리는 미분하는 기울기값의 절대값이 점점 줄어드는 원리이다.




W와 cost값이 어떻게 변하는지 원리를 알려주고 있다.


1. 그래프상에 곡선에서 임의의 점으로부터 시작한다.

2. 임의의 점에서 접선을 그어 기울기를 나타낸다. 그 기울기의 절대값은 줄어드는 방향으로 움직인다.

3. 반복한다

4. 최소값(w=1)으로 수렴한다.



# Lab 2 Linear Regression

import tensorflow as tf

tf.set_random_seed(777)  # for reproducibility


# Try to find values for W and b to compute y_data = W * x_data + b

# We know that W should be 1 and b should be 0

# But let's use TensorFlow to figure it out

W = tf.Variable(tf.random_normal([1]), name='weight')

b = tf.Variable(tf.random_normal([1]), name='bias')


# Now we can use X and Y in place of x_data and y_data

# # placeholders for a tensor that will be always fed using feed_dict

# See http://stackoverflow.com/questions/36693740/

'''

placeholder를 이용하여 x,y 노드를 만들수있다. 빈 노드를 만들고 노드에 값을 지정해줄수있다. 저번시간에 했던 x,y data를 미리 지정하지 않아도 된다.

'''

X = tf.placeholder(tf.float32, shape=[None])

Y = tf.placeholder(tf.float32, shape=[None])


# Our hypothesis XW+b

hypothesis = X * W + b


# cost/loss function

cost = tf.reduce_mean(tf.square(hypothesis - Y))


# Minimize

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

train = optimizer.minimize(cost)


# Launch the graph in a session.

sess = tf.Session()

# Initializes global variables in the graph.

sess.run(tf.global_variables_initializer())


# Fit the line

for step in range(2001):

    cost_val, W_val, b_val, _ = \

        sess.run([cost, W, b, train],

                 feed_dict={X: [1, 2, 3], Y: [1, 2, 3]}) 

#feed_dict -> placeholder로 지정된 노드에 값을 입력한다.

    if step % 20 == 0:

        print(step, cost_val, W_val, b_val)


# Learns best fit W:[ 1.],  b:[ 0]


# Testing our model

print(sess.run(hypothesis, feed_dict={X: [5]}))

print(sess.run(hypothesis, feed_dict={X: [2.5]}))

print(sess.run(hypothesis, feed_dict={X: [1.5, 3.5]}))

'''

첫번째 문장에서 hypothesis = 5가 나온다. w=1, b=0이기 때문에.

두번째 문장, 세번째 문장도 X와 hypothesis는 동일한 값을 갖게 된다.

'''


# Fit the line with new training data

for step in range(2001):

    cost_val, W_val, b_val, _ = \

        sess.run([cost, W, b, train],

                 feed_dict={X: [1, 2, 3, 4, 5],

                            Y: [2.1, 3.1, 4.1, 5.1, 6.1]})

    if step % 20 == 0:

        print(step, cost_val, W_val, b_val)


# Testing our model

print(sess.run(hypothesis, feed_dict={X: [5]}))

print(sess.run(hypothesis, feed_dict={X: [2.5]}))

print(sess.run(hypothesis, feed_dict={X: [1.5, 3.5]}))

'''

feed_dict 데이터로 x,y 그래프를 그리면 w=1, b=1.1이 나온다.

첫번째 출력은 5x1+1.1 = 6.1이 나오고

두번째,세번째도 같은 방법으로 hypothesis가 출력된다.

'''




X: 유저가 학습한 시간

Y: 유저가 받은 점수


-> X 데이터에 없는 유저(7시간학습)가 받는 점수를 예측하는것이 목표.



가설을 세우자.

H(x)=Wx + b라는 형태의 직선을 통해.




오른쪽 파란선(hypothesis)를 기준으로 밖에 있는 범위의 값(x 표시되어있는 3개)에 대해서 방정식으로 값을 유도 -> Cost function


cost = 1/m * (H(x)-y)^2 (양수가 되어야 하므로.)



hypothesis와 cost function을 정리




우리의 목표 -> cost 값을 최소로 하는것 -> 예측하는 근사치와 좀 더 가까워지는 경향.



# Lab 2 Linear Regression

#tf 라이브러리 입력, 난수 생성

import tensorflow as tf

tf.set_random_seed(777)  # for reproducibility



# X and Y data

x_train = [1, 2, 3]

y_train = [1, 2, 3]


# Try to find values for W and b to compute y_data = x_data * W + b

# We know that W should be 1 and b should be 0

# But let TensorFlow figure it out

W = tf.Variable(tf.random_normal([1]), name='weight')

b = tf.Variable(tf.random_normal([1]), name='bias')


# Our hypothesis XW+b

hypothesis = x_train * W + b


# cost/loss function

cost = tf.reduce_mean(tf.square(hypothesis - y_train))


# Minimize

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

train = optimizer.minimize(cost)


# Launch the graph in a session.

sess = tf.Session()

# Initializes global variables in the graph.

sess.run(tf.global_variables_initializer())


# Fit the line

for step in range(2001):

    sess.run(train)

    if step % 20 == 0:

        print(step, sess.run(cost), sess.run(W), sess.run(b))


# Learns best fit W:[ 1.],  b:[ 0.]


위 코드 정리하자면,

1. X_data, Y_data로 w,b 값을 도출해내어야 한다.

2. X,Y 그래프를 이용하여 3개 data를 표시한다

3. cost function이 minimize되게끔 w,b를 랜덤으로 정한다.

4. w,b값은 w->1, b->0으로 수렴한다.

5. 1차함수의 형태가 random -> y=x 꼴로 바뀐다.

 



영상파일에서 얼굴 감지하기


import cv2


#괄호안에 파일명을 쓰면 파일이 로드됌

#detecting한 얼굴을 표시할 폰트 정의

cap = cv2.VideoCapture('newface.mp4') #카메라 생성

font = cv2.FONT_HERSHEY_SIMPLEX


#create the window & change the window size

#윈도우 생성 및 사이즈 변경

cv2.namedWindow('Face')


#haar 코드 사용(frontal_face) -> 어떤 파일을 쓰느냐에 따라 인식할 객체가 달라짐

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')


while(True):

    #read the camera image

    #카메라에서 이미지 얻기

    ret, frame = cap.read()


#(Blue, Green, Red 계열의 이미지를 gray이미지로 변환. BGR2GRAY)

    grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    

#gray로 변환된 이미지를 cascade를 이용하여 detect

    faces = face_cascade.detectMultiScale(grayframe, 1.8, 2, 0, (30, 30))


#얼굴을 인식하는 사각프레임에 대한 내용

#얼굴을 인식하는 사각프레임에 넣을 글자내용

    for (x,y,w,h) in faces:

        cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),3, 4, 0)

        cv2.putText(frame, 'Detected Face', (x-5, y-5), font, 0.9, (255,255,0),2)


#Face로 정의된 프레임을 보여준다

    cv2.imshow('Face',frame)


    #wait keyboard input until 10ms

    #300ms 동안 키입력 대기

    #키를 누르면 꺼진다. 사진의 형태에서 얼굴 감지

    """if cv2.waitKey(300) >= 0:

break"""


#영상의 형태에서 얼굴 감지, space 입력시 중지

    if cv2.waitKey(1) != 255:

        break;


#close the window

#윈도우 종료

cap.release()

cv2.destroyWindow('Face')


#BGR2GRAY와 cascade 

 


위 사진은 각각의 형태에 따른 이미지 색깔 분류이다.


<Gray 모델>

색(color) 정보를 사용하지 않고 밝기 정보만으로 영상을 표현하는 것이다. 검정색 0부터 흰색 255까지 총 256단계의 밝기값(intensity)으로 영상 픽셀값을 표현한다.


<RGB 모델>

가장 기보적인 색상모델로서 색(color)을 Red, Green, Blue의 3가지 성분의 조합으로 생각하는 것이다. RGB 모델에서 검은색은 R=G=B=0, 흰색은 R=G=B=255, 빨강색은 R=255, G=B=0, 노란색은 R=G=255, B=0로 표현된다. R=G=B인 경우는 무채색인 Gray 색상이 된다. R, G, B 각각은 0 ~ 255 사이의 값을 가질 수 있기 때문에 RGB 색상 모델을 사용하면 총 256*256*256 = 16,777,216가지의 색을 표현할 수 있다.


<HSV 모델>

Hue(색조), Saturation(채도), Value(명도)의 3가지 성분으로 색을 표현한다. Hue는 색조(예: 붉은색 계열인지 푸른색 계열인지, ...)를, Saturation은 그 색이 얼마나 선명한(순수한) 색인지를, Value는 밝기(intensity)를 나타낸다. HSV 모델은 우리가 색을 가장 직관적으로 표현할 수 있는 모델이며 또한 머리속에서 상상하는 색을 가장 쉽게 만들어낼 수 있는 모델이다. 영상처리/영상인식에서 HSV 모델을 사용할 때, H, S, V 각각은 0 ~ 255 사이의 값으로 표현된다. H 값은 색의 종류를 나타내기 때문에 크기는 의미가 없으며 단순한 인덱스(index)를 나타낸다. S 값은 0이면 무채색(gray 색), 255면 가장 선명한(순수한) 색임을 나타낸다. V 값은 작을수록 어둡고 클수록 밝은 색임을 나타낸다. HSV 색상 모델은 그림과 같이 원뿔(conic) 형태, 원기둥(cylindric) 형태가 있다. 둘의 차이는 색의 차이(difference)를 정량적으로 수치화하는 파트에서 설명하겠다.


<YCbCr 모델>

 RGB 색에서 밝기성분(Y)과 색차정보(Cb, Cr)를 분리하여 표현하는 색상모델이다. 위 5번째 그림은 위키페디아에 있는 그림으로  Y=128일 때의 CbCr 색상평면이다. 디지털 영상에서 Y, Cb, Cr은 각각 0 ~ 255 사이의 값을 가지며 Y가 커지면 위 그림이 전체적으로 밝아지고 Y가 작아지면 전체적으로 어두워진다. YCbCr 모델은 mpeg에서 사용되는 색상모델로서 인간의 눈이 밝기차에는 민감하지만 색차에는 상대적으로 둔감하다는 점을 이용해서 Y에는 많은 비트수(해상도)를 할당하고 Cb, Cr에는 낮은 비트수를 할당하는 방식으로 비디오를 압축한다. 따라서 비디오 데이터를 처리할 경우에 YCbCr 모델을 사용하면 별도의 색상변환을 하지 않아도 되는 장점을 갖는다. YCbCr 모델은 YUV 모델로도 불린다.


따라서 grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 이 문장을 통해 grayframe은 이미지를 BGR에서 GRAY로 바꿔주는 작업이다.

이 컬러를 회색으로 바꿔주는 작업을 하는 이유는 밑에 나와있다.



haar는 cascade function 접근 기반의 머신러닝이기 때문에 이미지를 gray color로 바꿔주어 위 이미지와 같이 처리한다.

눈은 눈 주위보다 어둡기때문에 검은색의 값이 많고, 콧대는 눈보다 밝기때문에 흰색의 값이 많다.

(gray컬러는 밝기, BGR, RGB컬러는 색상에 대한 값을 나타낸다.)


그러므로 영상에서 객체를 인식하는 순서는


1) 내가 갖고있는 new face 동영상을 불러온다

2) 동영상을 frame으로 인식한다. (영상은 이미지의 연속이므로)

3) frame을 gray 컬러로 바꾼다.

4) gray컬러로 바뀐 이미지를 grade에 따라 인식한다

5) 밝은픽셀영역의 평균-어두운픽셀영역의 평균 -> threshold (문턱)을 넘으면 사람얼굴에 대한 패턴 인지

6) 사람 얼굴 인지 -> 사각형으로 출력

7) 문자 출력



참고자료

http://opencv-python.readthedocs.io/en/latest/doc/01.imageStart/imageStart.html

http://vision0814.tistory.com/113

http://darkpgmr.tistory.com/66

http://hamait.tistory.com/510


웹캠에서 얼굴 인식하기


import cv2

import numpy as np

#라이브러리 등록


font = cv2.FONT_HERSHEY_SIMPLEX

#폰트 등록


def faceDetect():

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

#영상에서 인식할 소스 등록


try:

cap=cv2.VideoCapture(0)

#웹캠 활성화시키는 코드


except:

print('카메라 로딩 실패')

return


while True:

ret, frame = cap.read()

if not ret:

return

   

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

faces = face_cascade.detectMultiScale(gray, 1.3, 2, 0, (30, 30))

   

for (x,y,w,h) in faces:

cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),3, 4, 0)

cv2.putText(frame, 'Detected Face', (x-5, y-5), font, 0.9, (255,255,0),2)

#얼굴을 인식하는 사각형에 대한 소스, 텍스트 소스



cv2.imshow('frame',frame)

#영상을 출력하는 소스


if cv2.waitKey(1) != 255:

                break;

cap.release()

cv2.destroyAllWindows()

#space를 누르면 실행 종료되는 코드


faceDetect()



얼굴에 대한 정보가 많이 부족해서 그런지 고개를 조금만 꺽어도 인식을 못하는 경우가 발생.



test1.jpg

(실험할 이미지)



test1_result.jpg

(실험 결과)




#얼굴 인식 소스


import numpy as np

import cv2

from matplotlib import pyplot as plt


#->라이브러리 생성

#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


#얼굴과 눈 검출을 위한 haarcascade 파일 읽기, CascadeClassifier 객체 생성

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')


#haarcascade 파일은 다운받아야 한다. (원하는 목록, eye, nose, face, body...)

#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


img = cv2.imread('test1.jpg')

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


#test1.jpg의 이미지를 불러들이고, 이미지를 흑백으로 바꿔준다

#이미지를 처리하는데에는 색깔이 필요없기 때문.

#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

#얼굴의 스케일을 조정한다.

#괄호안의 숫자를 바꾸면서 얼굴의 크기에따라 얼굴과 눈을 검출한다.

#괄호안의 숫자가 커질수록 작은 얼굴 감지할수있음

faces = face_cascade.detectMultiScale(gray, 1.9, 2) 


"""

    cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[,

                                           flags[, minSize[, maxSize]]]]]) → objects

    image 실제 이미지

    objects [반환값] 얼굴 검출 위치와 영역 변수

    scaleFactor 이미지 스케일

    minNeighbors 얼굴 검출 후보들의 갯수

    flags 이전 cascade와 동일하다 cvHaarDetectObjects 함수 에서

          새로운 cascade에서는 사용하지 않는다.

    minSize 가능한 최소 객체 사이즈

    maxSize 가능한 최대 객체 사이즈

"""

#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


for (x,y,w,h) in faces:

cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # (R,G,B)의 명도

roi_gray = gray[y:y+h, x:x+w]

roi_color = img[y:y+h, x:x+w]

"""

roi = region of interest

    cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) → None

    img 적용할 이미지

    pt1 그릴 상자의 꼭지점

    pt2 pt1의 반대편 꼭지점

    color 상자의 색상

    thickness 상자의 라인들의 두께 음수 또는 CV_FILLED를 주면 상자를 채운다.

    lineType 라인의 모양 line()함수 확인하기

    shift ?? Number of fractional bits in the point coordinates.

    포인트 좌표의 분수 비트의 수??

"""

#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


cv2.imshow('img',img)

cv2.waitKey(0)

cv2.destroyAllWindows()


#imshow를 통해 이미지를 출력한다., waitKey()에서 k는 꼭 대문자로 써야함.

#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

+ Recent posts