利用opencv建立一个识别手机的haar cascade分类器

一、安装和配置opencv

sudo apt-get install build-essential checkinstall cmake pkg-config yasm
sudo apt-get install git gfortran
sudo apt-get install libjpeg8-dev libjasper-dev libpng12-dev
 
# If you are using Ubuntu 14.04
sudo apt-get install libtiff4-dev
# If you are using Ubuntu 16.04
sudo apt-get install libtiff5-dev
 
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get install libxine2-dev libv4l-dev
sudo apt-get install libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt-get install qt5-default libgtk2.0-dev libtbb-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get install libvorbis-dev libxvidcore-dev
sudo apt-get install libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get install x264 v4l-utils
 
# Optional dependencies
sudo apt-get install libprotobuf-dev protobuf-compiler
sudo apt-get install libgoogle-glog-dev libgflags-dev
sudo apt-get install libgphoto2-dev libeigen3-dev libhdf5-dev doxygen

下载解压opencv opencv-contrib

安装python3库(可选)
sudo apt-get install python-dev python-pip python3-dev python3-pip
sudo -H pip2 install -U pip numpy
sudo -H pip3 install -U pip numpy

# Install virtual environment
sudo pip2 install virtualenv virtualenvwrapper
sudo pip3 install virtualenv virtualenvwrapper
echo "# Virtual Environment Wrapper"  >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
source ~/.bashrc
  
pip install numpy scipy matplotlib scikit-image scikit-learn ipython
  
编译和安装
cd opencv
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D INSTALL_C_EXAMPLES=ON \
      -D INSTALL_PYTHON_EXAMPLES=ON \
      -D WITH_TBB=ON \
      -D WITH_V4L=ON \
      -D WITH_QT=ON \
      -D WITH_OPENGL=ON \
      -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
      -D BUILD_EXAMPLES=ON ..

# find out number of CPU cores in your machine
nproc
# substitute 4 by output of nproc
make -j4
sudo make install
sudo sh -c 'echo "/usr/local/lib" >> /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

二、收集手机图片和非手机图片,形成正样本和负样本

可以通过百度图片,爬虫等方式获取自己需要的图片

三、标记正样本中手机所在的位置

执行命令:python3 object_marker.py /home/zhou/Desktop/github_summary/haar_cascade/result.txt /home/zhou/Desktop/github_summary/haar_cascade/sample/pos_color/
object_marker.py代码如下:

#!/usr/bin/python

###############################################################################
# Name      : ObjectMarker.py
# Author    : Python implementation: sqshemet 
#         Original ObjectMarker.cpp: http://www.cs.utah.edu/~turcsans/DUC_files/HaarTraining/
# Date      : 7/24/12
# Description   : Object marker utility to be used with OpenCV Haar training. 
#         Tested on Ubuntu Linux 10.04 with OpenCV 2.1.0.
# Usage     : python ObjectMarker.py outputfile inputdirectory
###############################################################################

import cv2
import sys
import os
import numpy as np

#shape = (1000,1000,3)
#image =  np.zeros(shape, np.uint8)
#image2 =  np.zeros(shape, np.uint8)
ratio=1
roi_x0 = 0
roi_y0 = 0
roi_x1 = 0
roi_y1 = 0
num_of_rec = 0
start_draw = False
window_name = "<Space> to save and load next, <X> to skip, <ESC> to exit."

def on_mouse(event, x, y, flag, params):
    global start_draw
    global roi_x0
    global roi_y0
    global roi_x1
    global roi_y1
    if (event == cv2.EVENT_LBUTTONDOWN):
        if (not start_draw):
            roi_x0 = x
            roi_y0 = y
            start_draw = True
        else:
            roi_x1 = x
            roi_y1 = y
            print("%d,%d" %(x, y))
            start_draw = False
    elif (event == cv2.EVENT_MOUSEMOVE and start_draw):
        #Redraw ROI selection
        image2 = image.copy()
        #print("%d,%d" %(x, y))
        #print(image2.shape)
        # x is ratio
        #cv2.rectangle(image2, (roi_x0, roi_y0), (x,roi_y0+int(ratio*(x-roi_x0))), 
            #(255,0,255),2)
        cv2.rectangle(image2, (roi_x0, roi_y0), (x,y), 
            (255),5)
        cv2.imshow(window_name, image2)

def main():
# Might want to divide this a bit more.
    global image
    iKey = 0
    
    if (len(sys.argv) != 3):
        sys.stderr.write("%s output_info.txt raw/data/directory\n" 
            % sys.argv[0])
        return -1

    input_directory = sys.argv[2]
    output_file = sys.argv[1]

    #Get a file listing of all files within the input directory
    try:
        files = os.listdir(input_directory)
    except OSError:
        sys.stderr.write("Failed to open dirctory %s\n" 
            % input_directory)
        return -1

    files.sort()

    sys.stderr.write("ObjectMarker: Input Directory: %s Output File %s\n" 
            % (input_directory, output_file))

    # init GUI
    cv2.namedWindow(window_name, 0)
    cv2.setMouseCallback(window_name, on_mouse, None)

    sys.stderr.write("Opening directory...")
    # init output of rectangles to the info file
    #os.chdir(input_directory)
    sys.stderr.write("done.\n")

    str_prefix = input_directory

    try:
        output = open(output_file,'a+')
    except IOError:
        sys.stderr.write("Failed to open file %s.\n" % output_file)
        return -1

    for file in files:
        str_postfix = ""
        num_of_rec = 0
        img = str_prefix + file
        sys.stderr.write("Loading image %s...\n" % img)

        try: 
            image = cv2.imread(img,cv2.IMREAD_UNCHANGED)
        except IOError: 
            sys.stderr.write("Failed to load image %s.\n" % img)
            return -1

        #  Work on current image
        
        cv2.imshow(window_name, image)
        # Need to figure out waitkey returns.
        # <ESC> = 27        exit program
        # <Space> = 32      add rectangle to current image
        # <x> = 120     skip image  keycode
        iKey = cv2.waitKey(0) % 255
        # This is ugly, but is actually a simplification of the C++.
        if iKey == 27:
            cv2.destroyWindow(window_name)
            return 0
        elif iKey == 32:
            print(1)
            num_of_rec += 1
            # Currently two draw directions possible:
            # from top left to bottom right or vice versa
            if (roi_x0<roi_x1 and roi_y0<roi_y1):
                str_postfix += " %d %d %d %d\n" % (roi_x0,
                    roi_y0, (roi_x1-roi_x0), (roi_y1-roi_y0))
            elif (roi_x0>roi_x1 and roi_y0>roi_y1):
                str_postfix += " %d %d %d %d\n" % (roi_x1, 
                    roi_y1, (roi_x0-roi_x1), (roi_y0-roi_y1))
            output.write(img + " " + str(num_of_rec) + str_postfix)
        elif iKey == 120:
            sys.stderr.write("Skipped %s.\n" % img)
        
if __name__ == '__main__':
    main()

四、训练haar cascade分类器

1.执行命令opencv_createsamples -info result.txt -vec positive.vec,生存vec样本文件
2.执行训练过程opencv_traincascade -data data -vec positive.vec -bg bg.txt -numStages 10 -numPos 50 -numNeg 100

五、验证haar cascade分类效果

import numpy as np
    import cv2 as cv
    face_cascade = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
    eye_cascade = cv.CascadeClassifier('haarcascade_eye.xml')
    img = cv.imread('sachin.jpg')
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
    cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex,ey,ew,eh) in eyes:
    cv.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
    cv.imshow('img',img)
    cv.waitKey(0)
    cv.destroyAllWindows()

猜你喜欢

转载自www.cnblogs.com/zyy-summary/p/11072773.html