利用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 cv2
import numpy as np
mobile_cascade = cv2.CascadeClassifier('cascade.xml')
cap=cv2.VideoCapture(3)
i=0
while True:
    ret,img=cap.read()
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces=mobile_cascade.detectMultiScale(gray,1.3,5)
    i+=1
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        cv2.imshow('img',img)
        k=cv2.waitKey(10) & 0xFF
    if i==30:
        break
cap.release()
cv2.destroyWindow('img')
posted @ 2019-06-23 14:30  繁华如梦个人笔记  阅读(1670)  评论(3编辑  收藏  举报