digits_video.py 2.7 KB
Newer Older
1 2
import numpy as np
import cv2
3
import os
A
Alexander Mordvintsev 已提交
4
import sys
5
import video
6 7
from common import mosaic

8
from digits import *
9 10

def main():
A
Alexander Mordvintsev 已提交
11 12 13
    try: src = sys.argv[1]
    except: src = 0
    cap = video.create_capture(src)
14 15 16 17 18

    classifier_fn = 'digits_svm.dat'
    if not os.path.exists(classifier_fn):
        print '"%s" not found, run digits.py first' % classifier_fn
        return 
19
    model = SVM()
A
Alexander Mordvintsev 已提交
20
    model.load(classifier_fn)
21

A
Alexander Mordvintsev 已提交
22
    
23 24 25 26
    while True:
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

A
Alexander Mordvintsev 已提交
27

28 29
        bin = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 31, 10)
        bin = cv2.medianBlur(bin, 3)
A
Alexander Mordvintsev 已提交
30 31 32
        contours, heirs = cv2.findContours( bin.copy(), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
        try: heirs = heirs[0]
        except: heirs = []
33

A
Alexander Mordvintsev 已提交
34 35 36
        for cnt, heir in zip(contours, heirs):
            _, _, _, outer_i = heir
            if outer_i >= 0:
37
                continue
A
Alexander Mordvintsev 已提交
38 39
            x, y, w, h = cv2.boundingRect(cnt)
            if not (16 <= h <= 64  and w <= 1.2*h):
40
                continue
A
Alexander Mordvintsev 已提交
41 42
            pad = max(h-w, 0)
            x, w = x-pad/2, w+pad
43 44
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0))

A
Alexander Mordvintsev 已提交
45 46
            bin_roi = bin[y:,x:][:h,:w]
            gray_roi = gray[y:,x:][:h,:w]
47

A
Alexander Mordvintsev 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61
            m = bin_roi != 0
            if not 0.1 < m.mean() < 0.4:
                continue
            '''
            v_in, v_out = gray_roi[m], gray_roi[~m]
            if v_out.std() > 10.0:
                continue
            s = "%f, %f" % (abs(v_in.mean() - v_out.mean()), v_out.std())
            cv2.putText(frame, s, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (200, 0, 0), thickness = 1)
            '''
            
            s = 1.5*float(h)/SZ
            m = cv2.moments(bin_roi)
            c1 = np.float32([m['m10'], m['m01']]) / m['m00']
62 63 64
            c0 = np.float32([SZ/2, SZ/2])
            t = c1 - s*c0
            A = np.zeros((2, 3), np.float32)
A
Alexander Mordvintsev 已提交
65
            A[:,:2] = np.eye(2)*s
66
            A[:,2] = t
A
Alexander Mordvintsev 已提交
67 68
            bin_norm = cv2.warpAffine(bin_roi, A, (SZ, SZ), flags=cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR)
            bin_norm = deskew(bin_norm)
A
Alexander Mordvintsev 已提交
69
            if x+w+SZ < frame.shape[1] and y+SZ < frame.shape[0]:
A
Alexander Mordvintsev 已提交
70
                frame[y:,x+w:][:SZ, :SZ] = bin_norm[...,np.newaxis]
A
Alexander Mordvintsev 已提交
71
                
A
Alexander Mordvintsev 已提交
72
            sample = preprocess_hog([bin_norm])
73 74 75 76 77 78
            digit = model.predict(sample)[0]
            cv2.putText(frame, '%d'%digit, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (200, 0, 0), thickness = 1)


        cv2.imshow('frame', frame)
        cv2.imshow('bin', bin)
A
Alexander Mordvintsev 已提交
79 80
        ch = cv2.waitKey(1)
        if ch == 27:
81 82 83 84
            break

if __name__ == '__main__':
    main()