├── 1_Image processing
├── Images
│ ├── arc.jpg
│ ├── lena.jpg
│ ├── line.jpg
│ ├── person.jpg
│ ├── plant.jpg
│ └── star.jpg
├── code
│ ├── 10_canny.py
│ ├── 11_edge.py
│ ├── 12_corner.py
│ ├── 13_add_noise.py
│ ├── 14_contour_detection.py
│ ├── 15_contours.py
│ ├── 16_Douglas-peucker.py
│ ├── 17_houghline.py
│ ├── 18_HoughCircles.py
│ ├── 1_image.py
│ ├── 2_resize.py
│ ├── 3_Change color channel.py
│ ├── 4_open.py
│ ├── 5_erode.py
│ ├── 6_sobel.py
│ ├── 7_canny.py
│ ├── 8_canny.py
│ └── 9_degeDetection.py
└── output_images
│ ├── 1.png
│ ├── 10.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.png
├── 2_Image segmentation
├── code
│ ├── 2.1_grabcut.py
│ ├── 2.2_grabcut_with-mouse.py
│ └── 2.3_watershed.py
├── imges
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── ouc.jpg
│ └── test.jpg
└── output
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ └── 5.png
├── 3_face_detection
├── cascade
│ ├── Readme
│ ├── haarcascade_eye.xml
│ ├── haarcascade_eye_tree_eyeglasses.xml
│ ├── haarcascade_frontalcatface.xml
│ ├── haarcascade_frontalcatface_extended.xml
│ ├── haarcascade_frontalface_alt.xml
│ ├── haarcascade_frontalface_alt2.xml
│ ├── haarcascade_frontalface_alt_tree.xml
│ ├── haarcascade_frontalface_default.xml
│ ├── haarcascade_fullbody.xml
│ ├── haarcascade_lefteye_2splits.xml
│ ├── haarcascade_licence_plate_rus_16stages.xml
│ ├── haarcascade_lowerbody.xml
│ ├── haarcascade_profileface.xml
│ ├── haarcascade_righteye_2splits.xml
│ ├── haarcascade_russian_plate_number.xml
│ ├── haarcascade_smile.xml
│ └── haarcascade_upperbody.xml
├── code
│ ├── 3.1_face_detection.py
│ ├── 3.2_face_video.py
│ ├── 3.3.1_face_recognition.py
│ ├── 3.3.2_trainset.py
│ ├── 3.3.3_recognition.py
│ └── Readme
├── data
│ ├── S1
│ │ ├── 1.pgm
│ │ ├── 10.pgm
│ │ ├── 2.pgm
│ │ ├── 3.pgm
│ │ ├── 4.pgm
│ │ ├── 5.pgm
│ │ ├── 6.pgm
│ │ ├── 7.pgm
│ │ ├── 8.pgm
│ │ ├── 9.pgm
│ │ └── Readme
│ └── ren_dong
│ │ └── Readme
├── images
│ ├── Readme
│ ├── face1.jpg
│ └── face2.jpg
└── output
│ └── 1.png
├── 4_Feature matching
├── code
│ ├── 4.1_Harris.py
│ ├── 4.2_SIFT.py
│ ├── 4.3_SURF.py
│ ├── 4.4_fast.py
│ ├── 4.5_ORB.py
│ ├── 4.6_KNN.py
│ ├── 4.7_FLANN.py
│ ├── 4.8_danyingxing.py
│ └── readme
├── images
│ ├── chess.jpg
│ ├── orb1.jpg
│ ├── orb2.jpg
│ └── readme
└── readme
├── 5_face_recognition
└── readme
├── 5_object_detection
├── code
│ ├── 5.1_person_detect.py
│ ├── 5.2_HOG.py
│ ├── 5.3_BOW.py
│ └── readme
├── images
│ ├── person.jpg
│ └── readme
└── readme
├── 6_object_traack
└── code
│ ├── 5.4_track.py
│ ├── 6.1_track.py
│ ├── 6.2_KNN.py
│ ├── 6.3_meanshift.py
│ ├── 6.4_camshift.py
│ └── readme
├── README.md
├── face_recognition
├── facial.py
├── find_face.py
├── find_face_cnn.py
├── images
│ ├── 001.jpg
│ ├── 002.jpg
│ ├── 003.jpg
│ ├── 004.jpg
│ ├── 11.jpg
│ ├── 22.jpg
│ ├── 33.jpg
│ └── readme
├── makeups.py
├── profile.py
└── readme
└── video2img
├── Readme
├── avi2img.py
└── img2avi.py
/1_Image processing/Images/arc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/Images/arc.jpg
--------------------------------------------------------------------------------
/1_Image processing/Images/lena.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/Images/lena.jpg
--------------------------------------------------------------------------------
/1_Image processing/Images/line.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/Images/line.jpg
--------------------------------------------------------------------------------
/1_Image processing/Images/person.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/Images/person.jpg
--------------------------------------------------------------------------------
/1_Image processing/Images/plant.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/Images/plant.jpg
--------------------------------------------------------------------------------
/1_Image processing/Images/star.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/Images/star.jpg
--------------------------------------------------------------------------------
/1_Image processing/code/10_canny.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | '''
3 | 带有滑动条的canny边缘检测
4 |
5 | '''
6 | import cv2
7 | import numpy as np
8 |
9 |
10 | def CannyThreshold(lowThreshold):
11 | detected_edges = cv2.GaussianBlur(gray,(3,3),0)
12 | detected_edges = cv2.Canny(detected_edges,lowThreshold,lowThreshold*ratio,apertureSize = kernel_size)
13 | dst = cv2.bitwise_and(img,img,mask = detected_edges) # just add some colours to edges from original image.
14 | cv2.imshow('canny demo',dst)
15 |
16 | lowThreshold = 0
17 | max_lowThreshold = 100
18 | ratio = 3
19 | kernel_size = 3
20 |
21 | img = cv2.imread('1.jpg')
22 | gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
23 |
24 | cv2.namedWindow('canny demo')
25 |
26 | cv2.createTrackbar('Min threshold','canny demo',lowThreshold, max_lowThreshold, CannyThreshold)
27 |
28 | CannyThreshold(0) # initialization
29 | if cv2.waitKey(0) == 27:
30 | cv2.destroyAllWindows()
31 |
--------------------------------------------------------------------------------
/1_Image processing/code/11_edge.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | import cv2
3 | import numpy
4 | '''
5 | 检测边缘
6 | 形态学检测边缘的原理很简单,在膨胀时,图像中的物体会想周围“扩张”;
7 | 腐蚀时,图像中的物体会“收缩”。比较这两幅图像,由于其变化的区域只发生在边缘。
8 | 所以这时将两幅图像相减,得到的就是图像中物体的边缘
9 |
10 | '''
11 |
12 | image = cv2.imread("1.jpg",0)
13 | #构造一个3×3的结构元素
14 | element = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
15 | dilate = cv2.dilate(image, element)
16 | erode = cv2.erode(image, element)
17 |
18 | #将两幅图像相减获得边,第一个参数是膨胀后的图像,第二个参数是腐蚀后的图像
19 | result = cv2.absdiff(dilate,erode)
20 | #上面得到的结果是灰度图,将其二值化以便更清楚的观察结果
21 | retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY)
22 | #反色,即对二值图每个像素取反
23 | result = cv2.bitwise_not(result)
24 | #显示图像
25 | cv2.imshow("result",result)
26 | cv2.waitKey(0)
27 | cv2.destroyAllWindows()
28 |
--------------------------------------------------------------------------------
/1_Image processing/code/12_corner.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | import cv2
3 | '''
4 | 检测拐角
5 | 与边缘检测不同,拐角的检测的过程稍稍有些复杂。
6 | 但原理相同,所不同的是先用十字形的结构元素膨胀像素,这种情况下只会在边缘处“扩张”,角点不发生变化。
7 | 接着用菱形的结构元素腐蚀原图像,导致只有在拐角处才会“收缩”,而直线边缘都未发生变化。
8 |
9 | 第二步是用X形膨胀原图像,角点膨胀的比边要多。这样第二次用方块腐蚀时,角点恢复原状,而边要腐蚀的更多。
10 | 所以当两幅图像相减时,只保留了拐角处
11 |
12 | '''
13 |
14 | image = cv2.imread("1.jpg", 0)
15 | origin = cv2.imread("1.jpg")
16 | #构造5×5的结构元素,分别为十字形、菱形、方形和X型
17 | cross = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
18 | #菱形结构元素的定义稍麻烦一些
19 | diamond = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
20 | diamond[0, 0] = 0
21 | diamond[0, 1] = 0
22 | diamond[1, 0] = 0
23 | diamond[4, 4] = 0
24 | diamond[4, 3] = 0
25 | diamond[3, 4] = 0
26 | diamond[4, 0] = 0
27 | diamond[4, 1] = 0
28 | diamond[3, 0] = 0
29 | diamond[0, 3] = 0
30 | diamond[0, 4] = 0
31 | diamond[1, 4] = 0
32 | square = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
33 | x = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
34 | #使用cross膨胀图像
35 | result1 = cv2.dilate(image,cross)
36 | #使用菱形腐蚀图像
37 | result1 = cv2.erode(result1, diamond)
38 |
39 | #使用X膨胀原图像
40 | result2 = cv2.dilate(image, x)
41 | #使用方形腐蚀图像
42 | result2 = cv2.erode(result2,square)
43 |
44 | #result = result1.copy()
45 | #将两幅闭运算的图像相减获得角
46 | result = cv2.absdiff(result2, result1)
47 | #使用阈值获得二值图
48 | retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY)
49 |
50 | #在原图上用半径为5的圆圈将点标出。
51 | for j in range(result.size):
52 | y = j / result.shape[0]
53 | x = j % result.shape[0]
54 |
55 | if result[x, y] == 255:
56 | cv2.circle(image, (y, x), 5, (255,0,0))
57 |
58 | cv2.imshow("Result", image)
59 | cv2.waitKey(0)
60 | cv2.destroyAllWindows()
61 |
--------------------------------------------------------------------------------
/1_Image processing/code/13_add_noise.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from numpy import *
4 | from scipy import *
5 | import numpy as np
6 | import cv2
7 | import os
8 |
9 | ''''
10 | 对指定文件夹进行图片遍历,并添加椒盐和高斯噪声,可以进行数据增强
11 |
12 | '''
13 |
14 | #定义添加椒盐噪声的函数
15 | def SaltAndPepper(src,percetage):
16 | SP_NoiseImg=src
17 | SP_NoiseNum=int(percetage*src.shape[0]*src.shape[1])
18 | for i in range(SP_NoiseNum):
19 | randX=random.random_integers(0,src.shape[0]-1)
20 | randY=random.random_integers(0,src.shape[1]-1)
21 | if random.random_integers(0,1)==0:
22 | SP_NoiseImg[randX,randY]=0
23 | else:
24 | SP_NoiseImg[randX,randY]=255
25 | return SP_NoiseImg
26 | #定义添加高斯噪声的函数
27 | def addGaussianNoise(image,percetage):
28 | G_Noiseimg = image
29 | G_NoiseNum=int(percetage*image.shape[0]*image.shape[1])
30 | for i in range(G_NoiseNum):
31 | temp_x = np.random.randint(20,40)
32 | temp_y = np.random.randint(20,40)
33 | G_Noiseimg[temp_x][temp_y] = 255
34 | return G_Noiseimg
35 |
36 | '''
37 | 单张图片测试
38 | '''
39 | # img = cv2.imread("1.jpg")
40 | # cv2.imshow('org',img)
41 | # salt = SaltAndPepper(img, 0.01)
42 | # cv2.imshow('salt',salt)
43 | # gauss = addGaussianNoise(img, 0.01)
44 | # cv2.imshow('gauss',gauss)
45 | #
46 | # cv2.waitKey(0)
47 | # cv2.destroyAllWindows()
48 |
49 | '''
50 | 指定文件夹批量测试
51 |
52 | '''
53 | class Batch():
54 | def __init__(self):
55 | self.path = '/home/ren_dong/PycharmProjects/OpenCv/img'
56 | self.savepath = '/home/ren_dong/PycharmProjects/OpenCv/save/'
57 |
58 | def add_noise(self):
59 | filelist = os.listdir(self.path)
60 | total_num = len(filelist)
61 | i = 0
62 | n = 1
63 | while(n<=3):
64 | for item in filelist:
65 | if item.endswith('.jpg'):
66 |
67 | item = self.path + '/' + str(item)
68 | img = cv2.imread(item)
69 | cv2.imshow('org', img)
70 | percentage = 0.01
71 | percentage = percentage*(n+1)
72 |
73 | salt = SaltAndPepper(img, percentage)
74 |
75 | gauss = addGaussianNoise(salt, percentage)
76 |
77 | cv2.imshow('salt',salt)
78 | cv2.imshow('gauss',gauss)
79 |
80 | k = cv2.waitKey(0)
81 | if k == 27:
82 | cv2.destroyAllWindows()
83 | elif k == ord('s'):
84 | for count in range(1):
85 | cv2.imwrite(self.savepath + str(i) + '.jpg', salt)
86 | cv2.imwrite(self.savepath + str(i) + '0' + '.jpg', gauss)
87 | count += 1
88 | else:
89 | for count in range(1):
90 | cv2.imwrite(self.savepath + str(i) + '0' + '.jpg', gauss)
91 | count += 1
92 |
93 | i += 1
94 |
95 | n += 1
96 |
97 |
98 |
99 | if __name__ == '__main__':
100 | demo = Batch()
101 | demo.add_noise()
102 |
--------------------------------------------------------------------------------
/1_Image processing/code/14_contour_detection.py:
--------------------------------------------------------------------------------
1 | #-*_ coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | '''
5 | created on Tues jan 08:28:51 2018
6 | @author: ren_dong
7 |
8 | contour detection
9 | cv2.findContours() 寻找轮廓
10 | cv2.drawContours() 绘制轮廓
11 |
12 |
13 | '''
14 | #加载图像img
15 | img = cv2.imread('person.jpg')
16 | cv2.imshow('origin', img)
17 | '''
18 |
19 | 灰度化处理,注意必须调用cv2.cvtColor(),
20 | 如果直接使用cv2.imread('1.jpg',0),会提示图像深度不对,不符合cv2.CV_8U
21 |
22 |
23 | '''
24 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
25 | cv2.imshow('gray', gray)
26 |
27 | #调用cv2.threshold()进行简单阈值化,由灰度图像得到二值化图像
28 | # 输入图像必须为单通道8位或32位浮点型
29 | ret, thresh = cv2.threshold(gray, 127, 255, 0)
30 | cv2.imshow('thresh', thresh)
31 |
32 | #调用cv2.findContours()寻找轮廓,返回修改后的图像,轮廓以及他们的层次
33 | image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
34 | cv2.imshow('image', image)
35 |
36 |
37 | print('contours[0]:',contours[0])
38 | print('len(contours):',len(contours))
39 | print('hierarchy.shape:',hierarchy.shape)
40 | print('hierarchy:',hierarchy)
41 |
42 | #调用cv2.drawContours()在原图上绘制轮廓
43 | img = cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
44 | cv2.imshow('contours', img)
45 |
46 |
47 |
48 | cv2.waitKey()
49 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/1_Image processing/code/15_contours.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | '''
5 | created on Tues jan 09:36:30 2018
6 | @author:ren_dong
7 |
8 | cv2.boundingRect() 边界框即直边界矩形
9 | cv2.minAreaRect() 最小矩形区域即旋转的边界矩形
10 | cv2.minEnclosingCircle() 最小闭圆
11 |
12 | '''
13 | #载入图像img
14 | img = cv2.pyrDown(cv2.imread('star.jpg', cv2.IMREAD_UNCHANGED))
15 |
16 | #灰度化
17 | gray = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY)
18 |
19 | #二值化
20 | ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
21 |
22 | #寻找轮廓
23 | image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
24 | print('hierarchy[0]:', hierarchy[0])
25 | print('len(contours):', len(contours))
26 | print('hierarchy.shape:', hierarchy.shape)
27 |
28 | #遍历每一个轮廓
29 | for C in contours:
30 | #计算边界框坐标
31 | x, y, w, h = cv2.boundingRect(C)
32 |
33 | ##在Img图像上绘制矩形框,颜色为green, 线宽为2
34 | cv2.rectangle(img, (x, y), (x + w, y + h), (0,255,0), 2)
35 |
36 | #计算包围目标的最小矩形区域
37 | rect = cv2.minAreaRect(C)
38 |
39 | #计算最小矩形的坐标
40 | box = cv2.boxPoints(rect)
41 |
42 | #坐标变为整数
43 | box = np.int0(box)
44 |
45 | #绘制矩形框轮廓 颜色为red 线宽为3
46 | cv2.drawContours(img, [box], 0, (0,0,255),3)
47 |
48 | #最小闭圆的圆心和半径
49 | (x,y),radius = cv2.minEnclosingCircle(C)
50 |
51 | #转换为整型
52 | center = (int(x), int(y))
53 | radius = int(radius)
54 |
55 | #绘制最小闭圆
56 | img = cv2.circle(img,center, radius, (255, 0, 0), 2)
57 |
58 |
59 |
60 | cv2.drawContours(img,contours, -1, (0, 0, 255), 1)
61 | cv2.imshow('contours',img)
62 |
63 |
64 | cv2.waitKey()
65 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/1_Image processing/code/16_Douglas-peucker.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | '''
5 | created on Tues jan 10:49:30 2018
6 | @author:ren_dong
7 |
8 | 凸轮廓和Douglas-Peucker算法
9 |
10 | cv2.approxPloyDP()
11 | CV2.arcLength()
12 | cv2.convexHull()
13 |
14 | '''
15 | #读入图像img
16 | img = cv2.pyrDown(cv2.imread('arc.jpg', cv2.IMREAD_COLOR))
17 |
18 | #resize
19 | #img = cv2.resize(img, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_CUBIC)
20 |
21 | #创建空白图像,用来绘制多边形轮廓
22 | curve = np.zeros(img.shape,np.uint8)
23 |
24 | #灰度变换
25 | gray = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY)
26 |
27 | #使用定制kernel 进行中值滤波,去除一些噪声
28 | kernel = np.ones((3,3),np.float32) / 9
29 | #这里的-1表示目标图像和原图像具有同样的深度,比如cv2.CV_8U
30 | gray = cv2.filter2D(gray,-1,kernel)
31 |
32 | #阈值化 gray image --> binary image
33 | # 输入图像必须为单通道8位或32位浮点型
34 | # 这里使用cv2.THRESH_BINARY_INV 实现效果像素>125 设置为0(黑) 否则设置为255(白)
35 | ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
36 |
37 | #寻找轮廓 返回修改后的图像, 图像轮廓 以及他们的层次
38 | image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
39 |
40 |
41 | ##假设contours[0]为最大轮廓
42 | cnt = contours[0]
43 | max_area = cv2.contourArea(cnt)
44 |
45 | ##遍历contours, 和原始设置比较,获得最大轮廓区域
46 | for i in contours:
47 | if cv2.contourArea(i) > max_area:
48 | cnt = i
49 | max_area = cv2.contourArea(cnt)
50 | print('max_area:',max_area)
51 |
52 | ##获得轮廓周长
53 | epsilon = 0.01 * cv2.arcLength(cnt, True)
54 |
55 | #计算得到近似的多边形框
56 | approx = cv2.approxPolyDP(cnt, epsilon, True)
57 |
58 | #得到凸包
59 | hull = cv2.convexHull(cnt)
60 |
61 |
62 |
63 | print('contours', len(contours), type(contours))
64 | print('cnt.shape', cnt.shape, type(cnt))
65 | print('approx.shape', approx.shape, type(approx))
66 | print('hull.shape', hull.shape, type(hull))
67 |
68 |
69 |
70 | #在原图像得到原始的轮廓
71 | cv2.drawContours(img, contours, -1, (255, 0 , 0),2)
72 |
73 | #在空白图像中得到最大轮廓, 多边形轮廓, 凸包轮廓
74 | cv2.drawContours(curve, [cnt], -1, (0, 0, 255), 1) #
75 | cv2.drawContours(curve, [hull], -1, (0, 255, 0), 2) ##绿色多边形轮廓 线宽2
76 | cv2.drawContours(curve, [approx], -1, (255, 0, 0), 3) ##蓝色凸包轮廓 线宽3
77 |
78 |
79 | cv2.imshow('contours',img)
80 | cv2.imshow('all',curve)
81 |
82 |
83 | cv2.waitKey()
84 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/1_Image processing/code/17_houghline.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | '''
5 | created on Tues jan 13:57:30 2018
6 | @author:ren_dong
7 |
8 | Hough变换检测直线
9 |
10 | cv2.HoughLine()
11 | cv2.HoughLines()
12 |
13 |
14 | '''
15 | #载入图片img
16 | img = cv2.imread('line.jpg')
17 |
18 | #灰度化 --> gray
19 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
20 |
21 | ##中值滤波去除噪声 图像平滑
22 | gray = cv2.medianBlur(gray, ksize=3)
23 |
24 | #Canny边缘检测
25 | edges = cv2.Canny(gray, 50, 120)
26 |
27 |
28 | #最小直线长度, 更短的直线会被消除
29 | minLineLength = 10
30 |
31 | #最大线段间隙,一条线段的间隙长度大于这个值会被认为是两条分开的线段
32 | maxLineGap = 5
33 |
34 | ##Hough 变换检测直线
35 | lines = cv2.HoughLinesP(edges, 1, np.pi/180, 80, minLineLength, maxLineGap)
36 |
37 | for i in range(len(lines)):
38 | for x1, y1, x2, y2 in lines[i]:
39 | #给定两点 在原始图片绘制线段
40 | cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
41 |
42 |
43 | cv2.imshow('edges', edges)
44 | cv2.imshow('lines', img)
45 |
46 |
47 | cv2.waitKey()
48 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/1_Image processing/code/18_HoughCircles.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | '''
5 | created on Tues jan 14:37:10 2018
6 | @author:ren_dong
7 |
8 | Hough变换检测圆
9 |
10 | cv2.HoughCricles()
11 |
12 |
13 | '''
14 | #载入图片img
15 | img = cv2.imread('plant.jpg')
16 |
17 | #灰度化处理 --> gray image
18 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
19 |
20 | ##中值滤波 图像平滑
21 | gray = cv2.medianBlur(gray, 7)
22 |
23 | ##Hough变换检测圆
24 | circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 200,
25 | param1=200, param2=20, minRadius= 0, maxRadius=0 )
26 |
27 | circles = np.uint16(np.around(circles))
28 |
29 |
30 | ##绘制圆
31 | for i in circles[0,:]:
32 | cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
33 | cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 2)
34 |
35 |
36 | cv2.imshow('HoughCircles',img)
37 |
38 |
39 | cv2.waitKey()
40 | cv2.destroyAllWindows()
41 |
--------------------------------------------------------------------------------
/1_Image processing/code/1_image.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import numpy as np
3 | import cv2
4 | from matplotlib import pyplot as plt
5 |
6 | ##使用matplotlib显示图像
7 |
8 | ##彩色图像使用OpenCV加载时是BGR模式,但是matplotlib是RGB模式。
9 | '''
10 | img = cv2.imread('000028.jpg', 0)
11 | plt.imshow(img, cmap = 'gray', interpolation= 'bicubic')
12 | plt.xticks([]),plt.yticks([])
13 | plt.show()
14 |
15 | '''
16 |
17 | #使用opencv显示图像并保存
18 |
19 |
20 | img = cv2.imread('000028.jpg', 3)
21 | cv2.namedWindow('image', cv2.WINDOW_NORMAL) ##创建一个窗口,调整窗口大小
22 | cv2.imshow('image', img)
23 | k = cv2.waitKey(0)
24 | if k == ord('q'): #wait for q key to exit
25 | cv2.destroyAllWindows()
26 | elif k == ord('s'): #wait for 's' to save and exit
27 | cv2.imwrite('1.jpg', img)
28 | img1 = cv2.imread('1.jpg', 0)
29 | cv2.imshow('gray', img1)
30 | cv2.waitKey(0)
31 | cv2.destroyAllWindows()
32 |
33 |
--------------------------------------------------------------------------------
/1_Image processing/code/2_resize.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 | 几何变换
7 |
8 | '''
9 | # #resize
10 | # img = cv2.imread('1.jpg')
11 | #
12 | # ##不指定具体尺寸, 按照比例进行resize
13 | # # res = cv2.resize(img,None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)
14 | #
15 | # ###直接给定缩放尺寸
16 | # res = cv2.resize(img, (640,480),interpolation=cv2.INTER_LINEAR)
17 | #
18 | # while(1):
19 | # cv2.imshow('img',img)
20 | # cv2.imshow('res',res)
21 | #
22 | # k = cv2.waitKey(1) & 0xff
23 | # if k == 27 :
24 | # break
25 | #
26 | # cv2.destroyWindow()
27 |
28 | ##rotation
29 |
30 | img = cv2.imread('1.jpg')
31 |
32 | rows, cols, ch = img.shape
33 |
34 | ###给定旋转矩阵 2*3
35 | M = cv2.getRotationMatrix2D((rows/2,cols/2), 30, 0.8)
36 |
37 | dst = cv2.warpAffine(img, M, (2*rows,2*cols))
38 |
39 | cv2.imshow('img',img)
40 | cv2.imshow('res',dst)
41 | cv2.waitKey(0)
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/1_Image processing/code/3_Change color channel.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 | 使用numpy索引制定图片通道,改变相应像素值,CV加载彩色图像为BGR
7 |
8 | '''
9 |
10 | img = cv2.imread('1.jpg')
11 | print img.shape
12 | print img.size
13 | print img.dtype
14 | img[:,:,2] = 0 ###0,1,2 = B, R, G
15 | cv2.imshow('img',img)
16 | k = cv2.waitKey(0)
17 | if k == 27:
18 | cv2.destroyAllWindows()
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/1_Image processing/code/4_open.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import cv2
3 | import numpy as np
4 | '''
5 |
6 | 开运算和闭运算就是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的,即先开后闭并不能得到原先的图像
7 | 闭运算用来连接被误分为许多小块的对象,而开运算用于移除由图像噪音形成的斑点
8 | 因此,某些情况下可以连续运用这两种运算。如对一副二值图连续使用闭运算和开运算,将获得图像中的主要对象。
9 | 同样,如果想消除图像中的噪声(即图像中的“小点”),也可以对图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。
10 |
11 |
12 | '''
13 | img = cv2.imread('1.jpg', 0)
14 | # 定义结构元素
15 | kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
16 |
17 | # 闭运算
18 | closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
19 | # 显示腐蚀后的图像
20 | cv2.imshow("Close", closed)
21 |
22 | # 开运算
23 | opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
24 | # 显示腐蚀后的图像
25 | cv2.imshow("Open", opened)
26 |
27 | cv2.waitKey(0)
28 | cv2.destroyAllWindows()
29 |
--------------------------------------------------------------------------------
/1_Image processing/code/5_erode.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 | 腐蚀和膨胀
7 | 腐蚀和膨胀的处理很简单,只需设置好结构元素,然后分别调用cv2.erode(...)和cv2.dilate(...)函数即可,
8 | 其中第一个参数是需要处理的图像,第二个是结构元素。返回处理好的图像。
9 | '''
10 | img = cv2.imread('1.jpg', 0)
11 | # OpenCV定义的结构元素
12 | kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
13 | # 腐蚀图像
14 | eroded = cv2.erode(img, kernel)
15 | # 显示腐蚀后的图像
16 | cv2.imshow("Eroded Image", eroded)
17 |
18 | # 膨胀图像
19 | dilated = cv2.dilate(img, kernel)
20 | # 显示膨胀后的图像
21 | cv2.imshow("Dilated Image", dilated)
22 | # 原图像
23 | cv2.imshow("Origin", img)
24 |
25 | # NumPy定义的结构元素
26 | NpKernel = np.uint8(np.ones((3, 3)))
27 | Nperoded = cv2.erode(img, NpKernel)
28 | # 显示腐蚀后的图像
29 | cv2.imshow("Eroded by NumPy kernel", Nperoded)
30 |
31 | cv2.waitKey(0)
32 | cv2.destroyAllWindows()
33 |
--------------------------------------------------------------------------------
/1_Image processing/code/6_sobel.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 | '''
3 | sobel算子 uint8 8维无符号数
4 | cv2.cv_16s 16维有符号数
5 |
6 | '''
7 |
8 | import cv2
9 |
10 | img = cv2.imread('1.jpg', 0)
11 |
12 | x = cv2.Sobel(img,cv2.CV_16S,1,0) #对x方向进行求导1,0
13 | y = cv2.Sobel(img,cv2.CV_16S,0,1) #对y方向进行求导0,1,选用cv_16s 避免图像显示不全
14 |
15 | absX = cv2.convertScaleAbs(x) ##对x,和y方向进行还原uint8,用来显示图片
16 | absY = cv2.convertScaleAbs(y)
17 |
18 | dst = cv2.addWeighted(absX,0.5,absY,0.5,0)
19 |
20 | cv2.imshow("absX", absX)
21 | cv2.imshow("absY", absY)
22 |
23 | cv2.imshow("Result", dst)
24 |
25 | cv2.waitKey(0)
26 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/1_Image processing/code/7_canny.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | '''
5 | Canny边缘检测
6 | 1 使用高斯滤波器进行去除图像噪声
7 | 2 计算图像梯度
8 | 3 非极大值抑制
9 | 4 滞后阈值即在检测边缘上使用双阈值去除假阳性
10 | 5 分析所有边缘与其之间的连接,以保留真正的边缘消除不明显的边缘
11 |
12 | '''
13 | img = cv2.imread('1.jpg')
14 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
15 | img = cv2.GaussianBlur(gray, (3,3), 0)
16 | canny = cv2.Canny(img,20,100)
17 |
18 | cv2.imshow('canny',canny)
19 | cv2.waitKey(0)
20 | cv2.destroyAllWindows()
21 |
22 |
--------------------------------------------------------------------------------
/1_Image processing/code/8_canny.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | '''
3 | 带有滑动条的canny边缘检测
4 |
5 | '''
6 | import cv2
7 | import numpy as np
8 |
9 |
10 | def CannyThreshold(lowThreshold):
11 | detected_edges = cv2.GaussianBlur(gray,(3,3),0)
12 | detected_edges = cv2.Canny(detected_edges,lowThreshold,lowThreshold*ratio,apertureSize = kernel_size)
13 | dst = cv2.bitwise_and(img,img,mask = detected_edges) # just add some colours to edges from original image.
14 | cv2.imshow('canny demo',dst)
15 |
16 | lowThreshold = 0
17 | max_lowThreshold = 100
18 | ratio = 3
19 | kernel_size = 3
20 |
21 | img = cv2.imread('1.jpg')
22 | gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
23 |
24 | cv2.namedWindow('canny demo')
25 |
26 | cv2.createTrackbar('Min threshold','canny demo',lowThreshold, max_lowThreshold, CannyThreshold)
27 |
28 | CannyThreshold(0) # initialization
29 | if cv2.waitKey(0) == 27:
30 | cv2.destroyAllWindows()
31 |
--------------------------------------------------------------------------------
/1_Image processing/code/9_degeDetection.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 | import numpy as np
3 | import cv2
4 |
5 | '''
6 | 自定义函数进行边缘检测
7 | 1 使用medianBlur()作为模糊函数,去除彩色图像的噪声
8 | 2 灰度化
9 | 3 使用Laplacian()作为边缘检测函数,产生边缘线条
10 | 4 归一化 并进行边缘和背景的黑白转换(之前是背景黑,边缘白,乘以原图像将边缘变黑)
11 |
12 | '''
13 |
14 | def strokeEdge(src, blurKsize = 7, edgeKsize = 5):
15 | '''
16 |
17 | :param src: 原图像 BGR彩色空间
18 | :param blurKsize: 模糊滤波器kernel size k<3 不进行模糊操作
19 | :param edgeKsize: 边缘检测kernel size
20 | :return: dst
21 |
22 |
23 | '''
24 | if blurKsize >= 3:
25 | ##中值模糊
26 | blurredSrc = cv2.medianBlur(src, blurKsize)
27 | #灰度化
28 | gray = cv2.cvtColor(blurredSrc, cv2.COLOR_BGR2GRAY)
29 | else:
30 | #灰度化
31 | gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
32 |
33 | cv2.imshow('gray',gray)
34 | ###边缘检测
35 | laplacian = cv2.Laplacian(gray, cv2.CV_8U, gray, ksize= edgeKsize)
36 | cv2.imshow('Laplacian',laplacian)
37 | ##归一化 转换背景
38 | normalizeInverse = (1.0/255)*(255- gray)
39 | cv2.imshow('normalizeInverse', normalizeInverse)
40 | ##分离通道
41 | channels = cv2.split(src)
42 |
43 | ##计算后的结果与每个通道相乘
44 | for channel in channels:
45 | ##这里是点乘 即对应原素相乘
46 | channel[:] = channel * normalizeInverse
47 |
48 | cv2.imshow('B',channels[0])
49 | #合并通道
50 | return cv2.merge(channels)
51 |
52 |
53 | img = cv2.imread('1.jpg',cv2.IMREAD_COLOR)
54 | dst = strokeEdge(img)
55 | cv2.imshow('dst',dst)
56 | cv2.waitKey()
57 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/1_Image processing/output_images/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/1.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/10.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/2.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/3.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/4.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/5.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/6.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/7.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/8.png
--------------------------------------------------------------------------------
/1_Image processing/output_images/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/1_Image processing/output_images/9.png
--------------------------------------------------------------------------------
/2_Image segmentation/code/2.1_grabcut.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 | created on 08:10:27 2018-11-15
7 | @author:ren_dong
8 |
9 | Grabcut 图像分割
10 |
11 | 直接给定矩形区域作为ROI
12 |
13 | GrabCut算法的实现步骤:
14 |
15 | 1 在图片中定义(一个或者多个)包含物体的矩形。
16 | 2 矩形外的区域被自动认为是背景。
17 | 3 对于用户定义的矩形区域,可用背景中的数据来区分它里面的前景和背景区域。
18 | 4 用高斯混合模型(GMM)来对背景和前景建模,并将未定义的像素标记为可能的前景或者背景。
19 | 5 图像中的每一个像素都被看做通过虚拟边与周围像素相连接,而每条边都有一个属于前景或者背景的概率,这是基于它与周边像素颜色上的相似性。
20 | 6 每一个像素(即算法中的节点)会与一个前景或背景节点连接。
21 | 7 在节点完成连接后(可能与背景或前景连接),若节点之间的边属于不同终端(即一个节点属于前景,另一个节点属于背景),则会切断他们之间的边,这就能将图像各部分分割出来。
22 |
23 |
24 | cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode]) → None
25 |
26 |
27 | '''
28 | #载入图像img
29 | fname = 'test.jpg'
30 | img = cv2.imread(fname)
31 |
32 | #设定矩形区域 作为ROI 矩形区域外作为背景
33 | rect = (275, 120, 170, 320)
34 |
35 | #img.shape[:2]得到img的row 和 col ,
36 | # 得到和img尺寸一样的掩模即mask ,然后用0填充
37 | mask = np.zeros(img.shape[:2], np.uint8)
38 |
39 | #创建以0填充的前景和背景模型, 输入必须是单通道的浮点型图像, 1行, 13x5 = 65的列 即(1,65)
40 | bgModel = np.zeros((1,65), np.float64)
41 | fgModel = np.zeros((1,65), np.float64)
42 |
43 | #调用grabcut函数进行分割,输入图像img, mask, mode为 cv2.GC_INIT_WITH-RECT
44 | cv2.grabCut(img, mask, rect, bgModel, fgModel, 5, cv2.GC_INIT_WITH_RECT)
45 |
46 | ##调用grabcut得到rect[0,1,2,3],将0,2合并为0, 1,3合并为1 存放于mask2中
47 | mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype(np.uint8)
48 |
49 | #得到输出图像
50 | out = img * mask2[:, :, np.newaxis]
51 |
52 | cv2.imshow('origin', img)
53 | cv2.imshow('grabcut', out)
54 | cv2.waitKey()
55 | cv2.destroyAllWindows()
56 |
57 |
--------------------------------------------------------------------------------
/2_Image segmentation/code/2.2_grabcut_with-mouse.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 | created on 08:10:27 2018-11-15
7 | @author:ren_dong
8 |
9 | Grabcut 图像分割
10 |
11 | 加入鼠标回调函数,可以进行交互式操作,鼠标选择矩形区域作为ROI
12 |
13 | cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode]) → None
14 | on_mouse()
15 |
16 |
17 | '''
18 |
19 | # 鼠标事件的回调函数
20 | def on_mouse(event, x, y, flag, param):
21 | global rect
22 | global leftButtonDown
23 | global leftButtonUp
24 |
25 | # 鼠标左键按下
26 | if event == cv2.EVENT_LBUTTONDOWN:
27 | rect[0] = x
28 | rect[2] = x
29 | rect[1] = y
30 | rect[3] = y
31 | leftButtonDown = True
32 | leftButtonUp = False
33 |
34 | # 移动鼠标事件
35 | if event == cv2.EVENT_MOUSEMOVE:
36 | if leftButtonDown and not leftButtonUp:
37 | rect[2] = x
38 | rect[3] = y
39 |
40 | # 鼠标左键松开
41 | if event == cv2.EVENT_LBUTTONUP:
42 | if leftButtonDown and not leftButtonUp:
43 | x_min = min(rect[0], rect[2])
44 | y_min = min(rect[1], rect[3])
45 |
46 | x_max = max(rect[0], rect[2])
47 | y_max = max(rect[1], rect[3])
48 |
49 | rect[0] = x_min
50 | rect[1] = y_min
51 | rect[2] = x_max
52 | rect[3] = y_max
53 | leftButtonDown = False
54 | leftButtonUp = True
55 |
56 |
57 | # 读入图片
58 | img = cv2.imread('ouc.jpg')
59 | '''
60 |
61 | 掩码图像,如果使用掩码进行初始化,那么mask保存初始化掩码信息;
62 | 在执行分割的时候,也可以将用户交互所设定的前景与背景保存到mask中,
63 | 然后再传入grabCut函数;
64 | 在处理结束之后,mask中会保存结果
65 |
66 | '''
67 | #img.shape[:2]=img.shape[0:2] 代表取彩色图像的长和宽 img.shape[:3] 代表取长+宽+通道
68 | mask = np.zeros(img.shape[:2], np.uint8)
69 |
70 | # 背景模型,如果为None,函数内部会自动创建一个bgdModel;bgdModel必须是单通道浮点型图像,且行数只能为1,列数只能为13x5;
71 | bgdModel = np.zeros((1, 65), np.float64)
72 | # fgdModel——前景模型,如果为None,函数内部会自动创建一个fgdModel;fgdModel必须是单通道浮点型图像,且行数只能为1,列数只能为13x5;
73 | fgdModel = np.zeros((1, 65), np.float64)
74 |
75 | # 用于限定需要进行分割的图像范围,只有该矩形窗口内的图像部分才被处理;
76 | # rect 初始化
77 | rect = [0, 0, 0, 0]
78 |
79 | # 鼠标左键按下
80 | leftButtonDown = False
81 | # 鼠标左键松开
82 | leftButtonUp = True
83 |
84 | # 指定窗口名来创建窗口
85 | cv2.namedWindow('img')
86 | # 设置鼠标事件回调函数 来获取鼠标输入
87 | cv2.setMouseCallback('img', on_mouse)
88 |
89 | # 显示图片
90 | cv2.imshow('img', img)
91 |
92 |
93 | ##设定循环,进行交互式操作
94 | while cv2.waitKey(2) == -1:
95 | # 左键按下,画矩阵
96 | if leftButtonDown and not leftButtonUp:
97 |
98 | img_copy = img.copy()
99 | # 在img图像上,绘制矩形 线条颜色为green 线宽为2
100 | cv2.rectangle(img_copy, (rect[0], rect[1]), (rect[2], rect[3]), (0, 255, 0), 2)
101 | # 显示图片
102 | cv2.imshow('img', img_copy)
103 |
104 | # 左键松开,矩形画好
105 | elif not leftButtonDown and leftButtonUp and rect[2] - rect[0] != 0 and rect[3] - rect[1] != 0:
106 | # 转换为宽度高度
107 | rect[2] = rect[2] - rect[0]
108 | rect[3] = rect[3] - rect[1]
109 | # rect_copy = tuple(rect.copy())
110 | rect_copy = tuple(rect)
111 | rect = [0, 0, 0, 0]
112 | # 物体分割
113 | cv2.grabCut(img, mask, rect_copy, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
114 |
115 | mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
116 | img_show = img * mask2[:, :, np.newaxis]
117 | # 显示图片分割后结果
118 | cv2.imshow('grabcut', img_show)
119 | # 显示原图
120 | cv2.imshow('img', img)
121 |
122 | cv2.waitKey()
123 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/2_Image segmentation/code/2.3_watershed.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 | created on 11:10:10 2018-11-15
7 | @author:ren_dong
8 |
9 | 分水岭算法 图像分割
10 |
11 | 分水岭算法实现图像自动分割的步骤:
12 |
13 | 1 图像灰度化、Canny边缘检测
14 | 2 查找轮廓,并且把轮廓信息按照不同的编号绘制到watershed的第二个参数markers上,相当于标记注水点。
15 | 3 watershed分水岭算法
16 | 4 绘制分割出来的区域,然后使用随机颜色填充,再跟源图像融合,以得到更好的显示效果。
17 |
18 |
19 | cv2.watershed(image, markers) → None
20 |
21 |
22 | '''
23 |
24 |
25 | # 读入图片
26 | img = cv2.imread('1.jpg')
27 | cv2.imshow('origin',img)
28 |
29 | # 转换为灰度图片
30 | gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
31 |
32 | # canny边缘检测 函数返回一副二值图,其中包含检测出的边缘。
33 | canny = cv2.Canny(gray_img, 80, 150)
34 | cv2.imshow('Canny', canny)
35 |
36 | # 寻找图像轮廓 返回修改后的图像 图像的轮廓 以及它们的层次
37 | canny, contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
38 |
39 | # 32位有符号整数类型
40 | marks = np.zeros(img.shape[:2], np.int32)
41 |
42 | # findContours检测到的轮廓
43 | imageContours = np.zeros(img.shape[:2], np.uint8)
44 |
45 | # 轮廓颜色
46 | compCount = 0
47 | index = 0
48 | # 绘制每一个轮廓
49 |
50 |
51 | for index in range(len(contours)):
52 |
53 | # 对marks进行标记,对不同区域的轮廓使用不同的亮度绘制,相当于设置注水点,有多少个轮廓,就有多少个注水点
54 | # 图像上不同线条的灰度值是不同的,底部略暗,越往上灰度越高
55 | marks = cv2.drawContours(marks, contours, index, (index, index, index), 1, 8, hierarchy)
56 |
57 | # 绘制轮廓,亮度一样
58 | # masks底部亮度暗,越往上亮度越高, imageContours 整体亮度一致
59 | # imageContours = cv2.drawContours(imageContours, contours, index, (255, 255, 255), 1, 8, hierarchy)
60 |
61 |
62 | # 查看 使用线性变换转换输入数组元素成8位无符号整型。
63 | markerShows = cv2.convertScaleAbs(marks)
64 | cv2.imshow('markerShows', markerShows)
65 | # cv2.imshow('imageContours',imageContours)
66 |
67 |
68 | # 使用分水岭算法
69 | marks = cv2.watershed(img, marks)
70 | afterWatershed = cv2.convertScaleAbs(marks)
71 |
72 | cv2.imshow('afterWatershed', afterWatershed)
73 |
74 | ###分水岭算法之后,让水漫起来,并且把堤坝即分水岭绘制为绿色
75 | img[marks == -1] = [ 0, 255, 0]
76 | cv2.imshow('masks',img)
77 |
78 | ###到此 分水岭算法已经算是完成,下面是利用numpy生成随机颜色,进行填充空白图像,然后将其和原图像融合
79 |
80 |
81 |
82 |
83 | # 生成随机颜色
84 | colorTab = np.zeros((np.max(marks) + 1, 3))
85 | # 生成0~255之间的随机数
86 | for i in range(len(colorTab)):
87 | aa = np.random.uniform(0, 255)
88 | bb = np.random.uniform(0, 255)
89 | cc = np.random.uniform(0, 255)
90 | colorTab[i] = np.array([aa, bb, cc], np.uint8)
91 |
92 | bgrImage = np.zeros(img.shape, np.uint8)
93 |
94 | # 遍历marks每一个元素值,对每一个区域进行颜色填充
95 | for i in range(marks.shape[0]):
96 | for j in range(marks.shape[1]):
97 | # index值一样的像素表示在一个区域
98 | index = marks[i][j]
99 | # 判断是不是区域与区域之间的分界,如果是边界(-1),则使用白色显示
100 | if index == -1:
101 | bgrImage[i][j] = np.array([255, 255, 255])
102 | else:
103 | bgrImage[i][j] = colorTab[index]
104 | cv2.imshow('After ColorFill', bgrImage)
105 |
106 | # 填充后与原始图像融合
107 | result = cv2.addWeighted(img, 0.55, bgrImage, 0.45, 0)
108 | cv2.imshow('addWeighted', result)
109 |
110 | cv2.waitKey()
111 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/2_Image segmentation/imges/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/imges/1.jpg
--------------------------------------------------------------------------------
/2_Image segmentation/imges/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/imges/2.jpg
--------------------------------------------------------------------------------
/2_Image segmentation/imges/ouc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/imges/ouc.jpg
--------------------------------------------------------------------------------
/2_Image segmentation/imges/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/imges/test.jpg
--------------------------------------------------------------------------------
/2_Image segmentation/output/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/output/1.png
--------------------------------------------------------------------------------
/2_Image segmentation/output/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/output/2.png
--------------------------------------------------------------------------------
/2_Image segmentation/output/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/output/3.png
--------------------------------------------------------------------------------
/2_Image segmentation/output/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/output/4.png
--------------------------------------------------------------------------------
/2_Image segmentation/output/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/2_Image segmentation/output/5.png
--------------------------------------------------------------------------------
/3_face_detection/cascade/Readme:
--------------------------------------------------------------------------------
1 | The cascade stores the Haar cascading file,
2 |
3 | that is, the xml file that holds the relevant feature matrix.
4 |
--------------------------------------------------------------------------------
/3_face_detection/cascade/haarcascade_licence_plate_rus_16stages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 64 16
7 |
8 | <_>
9 |
10 |
11 | <_>
12 |
13 | <_>
14 |
15 |
16 |
17 | <_>
18 | 32 2 8 6 -1.
19 | <_>
20 | 32 4 8 2 3.
21 | 0
22 | 1.6915600746870041e-002
23 | -9.5547717809677124e-001
24 | 8.9129137992858887e-001
25 | <_>
26 |
27 | <_>
28 |
29 |
30 |
31 | <_>
32 | 0 4 6 10 -1.
33 | <_>
34 | 3 4 3 10 2.
35 | 0
36 | 2.4228349328041077e-002
37 | -9.2089319229125977e-001
38 | 8.8723921775817871e-001
39 | <_>
40 |
41 | <_>
42 |
43 |
44 |
45 | <_>
46 | 55 0 8 6 -1.
47 | <_>
48 | 55 0 4 3 2.
49 | <_>
50 | 59 3 4 3 2.
51 | 0
52 | -1.0168660432100296e-002
53 | 8.8940089941024780e-001
54 | -7.7847331762313843e-001
55 | <_>
56 |
57 | <_>
58 |
59 |
60 |
61 | <_>
62 | 44 7 4 9 -1.
63 | <_>
64 | 44 10 4 3 3.
65 | 0
66 | 2.0863260142505169e-003
67 | -8.7998157739639282e-001
68 | 5.8651781082153320e-001
69 | -2.0683259963989258e+000
70 | -1
71 | -1
72 | <_>
73 |
74 |
75 | <_>
76 |
77 | <_>
78 |
79 |
80 |
81 | <_>
82 | 29 1 16 4 -1.
83 | <_>
84 | 29 3 16 2 2.
85 | 0
86 | 2.9062159359455109e-002
87 | -8.7765061855316162e-001
88 | 8.5373121500015259e-001
89 | <_>
90 |
91 | <_>
92 |
93 |
94 |
95 | <_>
96 | 0 5 9 8 -1.
97 | <_>
98 | 3 5 3 8 3.
99 | 0
100 | 2.3903399705886841e-002
101 | -9.2079448699951172e-001
102 | 7.5155001878738403e-001
103 | <_>
104 |
105 | <_>
106 |
107 |
108 |
109 | <_>
110 | 44 0 20 14 -1.
111 | <_>
112 | 44 0 10 7 2.
113 | <_>
114 | 54 7 10 7 2.
115 | 0
116 | -3.5404648631811142e-002
117 | 6.7834627628326416e-001
118 | -9.0937072038650513e-001
119 | <_>
120 |
121 | <_>
122 |
123 |
124 |
125 | <_>
126 | 41 7 6 9 -1.
127 | <_>
128 | 43 7 2 9 3.
129 | 0
130 | 6.2988721765577793e-003
131 | -8.1054258346557617e-001
132 | 5.8985030651092529e-001
133 | <_>
134 |
135 | <_>
136 |
137 |
138 |
139 | <_>
140 | 0 4 21 4 -1.
141 | <_>
142 | 7 4 7 4 3.
143 | 0
144 | 3.4959490876644850e-003
145 | -9.7632282972335815e-001
146 | 4.5473039150238037e-001
147 | -1.6632349491119385e+000
148 | 0
149 | -1
150 | <_>
151 |
152 |
153 | <_>
154 |
155 | <_>
156 |
157 |
158 |
159 | <_>
160 | 31 2 11 6 -1.
161 | <_>
162 | 31 4 11 2 3.
163 | 0
164 | 2.3864099755883217e-002
165 | -9.3137168884277344e-001
166 | 8.2478952407836914e-001
167 | <_>
168 |
169 | <_>
170 |
171 |
172 |
173 | <_>
174 | 56 3 6 11 -1.
175 | <_>
176 | 59 3 3 11 2.
177 | 0
178 | -2.5775209069252014e-002
179 | 8.5526448488235474e-001
180 | -8.7574672698974609e-001
181 | <_>
182 |
183 | <_>
184 |
185 |
186 |
187 | <_>
188 | 32 14 32 2 -1.
189 | <_>
190 | 32 15 32 1 2.
191 | 0
192 | -1.0646049864590168e-002
193 | 8.5167151689529419e-001
194 | -6.7789041996002197e-001
195 | <_>
196 |
197 | <_>
198 |
199 |
200 |
201 | <_>
202 | 0 2 8 14 -1.
203 | <_>
204 | 4 2 4 14 2.
205 | 0
206 | 2.7000989764928818e-002
207 | -8.0041092634201050e-001
208 | 6.4893317222595215e-001
209 | <_>
210 |
211 | <_>
212 |
213 |
214 |
215 | <_>
216 | 19 0 22 6 -1.
217 | <_>
218 | 19 0 11 3 2.
219 | <_>
220 | 30 3 11 3 2.
221 | 0
222 | 5.2989721298217773e-003
223 | -9.5342522859573364e-001
224 | 5.0140267610549927e-001
225 | -1.3346730470657349e+000
226 | 1
227 | -1
228 | <_>
229 |
230 |
231 | <_>
232 |
233 | <_>
234 |
235 |
236 |
237 | <_>
238 | 56 0 6 6 -1.
239 | <_>
240 | 56 0 3 3 2.
241 | <_>
242 | 59 3 3 3 2.
243 | 0
244 | -6.9233630783855915e-003
245 | 8.2654470205307007e-001
246 | -8.5396027565002441e-001
247 | <_>
248 |
249 | <_>
250 |
251 |
252 |
253 | <_>
254 | 32 0 14 12 -1.
255 | <_>
256 | 32 0 7 6 2.
257 | <_>
258 | 39 6 7 6 2.
259 | 0
260 | 1.2539249658584595e-001
261 | -1.2996139936149120e-002
262 | -3.2377028808593750e+003
263 | <_>
264 |
265 | <_>
266 |
267 |
268 |
269 | <_>
270 | 2 1 43 4 -1.
271 | <_>
272 | 2 3 43 2 2.
273 | 0
274 | 6.3474893569946289e-002
275 | -6.4648061990737915e-001
276 | 8.2302427291870117e-001
277 | <_>
278 |
279 | <_>
280 |
281 |
282 |
283 | <_>
284 | 34 10 30 5 -1.
285 | <_>
286 | 44 10 10 5 3.
287 | 0
288 | 4.2217150330543518e-002
289 | -7.5190877914428711e-001
290 | 6.3705182075500488e-001
291 | <_>
292 |
293 | <_>
294 |
295 |
296 |
297 | <_>
298 | 0 9 9 5 -1.
299 | <_>
300 | 3 9 3 5 3.
301 | 0
302 | 2.0000640302896500e-002
303 | -6.2077498435974121e-001
304 | 6.1317932605743408e-001
305 | -1.6521669626235962e+000
306 | 2
307 | -1
308 | <_>
309 |
310 |
311 | <_>
312 |
313 | <_>
314 |
315 |
316 |
317 | <_>
318 | 2 1 43 6 -1.
319 | <_>
320 | 2 3 43 2 3.
321 | 0
322 | 9.2297486960887909e-002
323 | -7.2764229774475098e-001
324 | 8.0554759502410889e-001
325 | <_>
326 |
327 | <_>
328 |
329 |
330 |
331 | <_>
332 | 53 4 9 8 -1.
333 | <_>
334 | 56 4 3 8 3.
335 | 0
336 | 2.7613969519734383e-002
337 | -7.0769268274307251e-001
338 | 7.3315787315368652e-001
339 | <_>
340 |
341 | <_>
342 |
343 |
344 |
345 | <_>
346 | 36 4 14 8 -1.
347 | <_>
348 | 36 4 7 4 2.
349 | <_>
350 | 43 8 7 4 2.
351 | 0
352 | 1.2465449981391430e-002
353 | -8.4359270334243774e-001
354 | 5.7046437263488770e-001
355 | <_>
356 |
357 | <_>
358 |
359 |
360 |
361 | <_>
362 | 14 14 49 2 -1.
363 | <_>
364 | 14 15 49 1 2.
365 | 0
366 | -2.3886829614639282e-002
367 | 8.2656508684158325e-001
368 | -5.2783298492431641e-001
369 | -1.4523630142211914e+000
370 | 3
371 | -1
372 | <_>
373 |
374 |
375 | <_>
376 |
377 | <_>
378 |
379 |
380 |
381 | <_>
382 | 0 5 4 9 -1.
383 | <_>
384 | 2 5 2 9 2.
385 | 0
386 | 1.8821349367499352e-002
387 | -8.1122857332229614e-001
388 | 6.9127470254898071e-001
389 | <_>
390 |
391 | <_>
392 |
393 |
394 |
395 | <_>
396 | 21 1 38 4 -1.
397 | <_>
398 | 21 3 38 2 2.
399 | 0
400 | 6.1703320592641830e-002
401 | -7.6482647657394409e-001
402 | 6.4212161302566528e-001
403 | <_>
404 |
405 | <_>
406 |
407 |
408 |
409 | <_>
410 | 44 12 18 3 -1.
411 | <_>
412 | 53 12 9 3 2.
413 | 0
414 | -1.6298670321702957e-002
415 | 5.0207728147506714e-001
416 | -8.4020161628723145e-001
417 | <_>
418 |
419 | <_>
420 |
421 |
422 |
423 | <_>
424 | 10 4 9 3 -1.
425 | <_>
426 | 13 4 3 3 3.
427 | 0
428 | -4.9458951689302921e-003
429 | 6.1991941928863525e-001
430 | -6.1633539199829102e-001
431 | <_>
432 |
433 | <_>
434 |
435 |
436 |
437 | <_>
438 | 40 4 10 4 -1.
439 | <_>
440 | 45 4 5 4 2.
441 | 0
442 | -5.1894597709178925e-003
443 | 4.4975179433822632e-001
444 | -8.0651968717575073e-001
445 | <_>
446 |
447 | <_>
448 |
449 |
450 |
451 | <_>
452 | 17 14 47 2 -1.
453 | <_>
454 | 17 15 47 1 2.
455 | 0
456 | -1.8824130296707153e-002
457 | 6.1992841958999634e-001
458 | -5.5643159151077271e-001
459 | <_>
460 |
461 | <_>
462 |
463 |
464 |
465 | <_>
466 | 8 5 4 7 -1.
467 | <_>
468 | 10 5 2 7 2.
469 | 0
470 | 5.6571601890027523e-003
471 | -4.8346561193466187e-001
472 | 6.8647360801696777e-001
473 | -2.2358059883117676e+000
474 | 4
475 | -1
476 | <_>
477 |
478 |
479 | <_>
480 |
481 | <_>
482 |
483 |
484 |
485 | <_>
486 | 56 0 6 6 -1.
487 | <_>
488 | 56 0 3 3 2.
489 | <_>
490 | 59 3 3 3 2.
491 | 0
492 | -9.1503243893384933e-003
493 | 6.8174481391906738e-001
494 | -7.7866071462631226e-001
495 | <_>
496 |
497 | <_>
498 |
499 |
500 |
501 | <_>
502 | 0 0 6 6 -1.
503 | <_>
504 | 0 0 3 3 2.
505 | <_>
506 | 3 3 3 3 2.
507 | 0
508 | 7.4933180585503578e-003
509 | -6.8696027994155884e-001
510 | 6.6913938522338867e-001
511 | <_>
512 |
513 | <_>
514 |
515 |
516 |
517 | <_>
518 | 13 4 48 2 -1.
519 | <_>
520 | 29 4 16 2 3.
521 | 0
522 | 4.5296419411897659e-002
523 | -7.3576509952545166e-001
524 | 5.9453499317169189e-001
525 | <_>
526 |
527 | <_>
528 |
529 |
530 |
531 | <_>
532 | 42 1 6 15 -1.
533 | <_>
534 | 42 6 6 5 3.
535 | 0
536 | 1.1669679544866085e-002
537 | -8.4733831882476807e-001
538 | 4.5461329817771912e-001
539 | <_>
540 |
541 | <_>
542 |
543 |
544 |
545 | <_>
546 | 30 8 3 5 -1.
547 | <_>
548 | 31 8 1 5 3.
549 | 0
550 | 2.5769430212676525e-003
551 | -5.8270388841629028e-001
552 | 7.7900522947311401e-001
553 | <_>
554 |
555 | <_>
556 |
557 |
558 |
559 | <_>
560 | 55 10 8 6 -1.
561 | <_>
562 | 55 13 8 3 2.
563 | 0
564 | -1.4139170525595546e-003
565 | 4.5126929879188538e-001
566 | -9.0696328878402710e-001
567 | -1.8782069683074951e+000
568 | 5
569 | -1
570 | <_>
571 |
572 |
573 | <_>
574 |
575 | <_>
576 |
577 |
578 |
579 | <_>
580 | 4 6 4 7 -1.
581 | <_>
582 | 6 6 2 7 2.
583 | 0
584 | -5.3149578161537647e-003
585 | 6.5218788385391235e-001
586 | -7.9464268684387207e-001
587 | <_>
588 |
589 | <_>
590 |
591 |
592 |
593 | <_>
594 | 56 3 6 8 -1.
595 | <_>
596 | 59 3 3 8 2.
597 | 0
598 | -2.2906960919499397e-002
599 | 6.6433382034301758e-001
600 | -7.3633247613906860e-001
601 | <_>
602 |
603 | <_>
604 |
605 |
606 |
607 | <_>
608 | 37 2 4 6 -1.
609 | <_>
610 | 37 4 4 2 3.
611 | 0
612 | 9.4887977465987206e-003
613 | -8.2612031698226929e-001
614 | 4.9333500862121582e-001
615 | <_>
616 |
617 | <_>
618 |
619 |
620 |
621 | <_>
622 | 0 10 30 6 -1.
623 | <_>
624 | 0 12 30 2 3.
625 | 0
626 | 4.5138411223888397e-002
627 | -5.4704028367996216e-001
628 | 7.6927912235260010e-001
629 | <_>
630 |
631 | <_>
632 |
633 |
634 |
635 | <_>
636 | 0 4 21 12 -1.
637 | <_>
638 | 7 4 7 12 3.
639 | 0
640 | 2.5049019604921341e-002
641 | -8.6739641427993774e-001
642 | 5.2807968854904175e-001
643 | -1.0597369670867920e+000
644 | 6
645 | -1
646 | <_>
647 |
648 |
649 | <_>
650 |
651 | <_>
652 |
653 |
654 |
655 | <_>
656 | 44 0 1 14 -1.
657 | <_>
658 | 44 7 1 7 2.
659 | 0
660 | 6.6414438188076019e-003
661 | -7.7290147542953491e-001
662 | 6.9723731279373169e-001
663 | <_>
664 |
665 | <_>
666 |
667 |
668 |
669 | <_>
670 | 54 3 4 3 -1.
671 | <_>
672 | 56 3 2 3 2.
673 | 0
674 | 2.4703629314899445e-003
675 | -7.4289917945861816e-001
676 | 6.6825848817825317e-001
677 | <_>
678 |
679 | <_>
680 |
681 |
682 |
683 | <_>
684 | 32 0 30 6 -1.
685 | <_>
686 | 32 0 15 3 2.
687 | <_>
688 | 47 3 15 3 2.
689 | 0
690 | -2.2910499945282936e-002
691 | 4.3986389040946960e-001
692 | -9.0588808059692383e-001
693 | <_>
694 |
695 | <_>
696 |
697 |
698 |
699 | <_>
700 | 0 8 9 7 -1.
701 | <_>
702 | 3 8 3 7 3.
703 | 0
704 | 3.4193221479654312e-002
705 | -6.9507479667663574e-001
706 | 6.2501090764999390e-001
707 | <_>
708 |
709 | <_>
710 |
711 |
712 |
713 | <_>
714 | 30 10 3 3 -1.
715 | <_>
716 | 31 10 1 3 3.
717 | 0
718 | 1.5060020377859473e-003
719 | -6.8670761585235596e-001
720 | 8.2241541147232056e-001
721 | <_>
722 |
723 | <_>
724 |
725 |
726 |
727 | <_>
728 | 21 3 24 4 -1.
729 | <_>
730 | 29 3 8 4 3.
731 | 0
732 | 1.9838380467263050e-005
733 | -9.2727631330490112e-001
734 | 6.4723730087280273e-001
735 | <_>
736 |
737 | <_>
738 |
739 |
740 |
741 | <_>
742 | 42 3 12 6 -1.
743 | <_>
744 | 46 3 4 6 3.
745 | 0
746 | -2.2170299416757189e-005
747 | 5.6555831432342529e-001
748 | -9.6788132190704346e-001
749 | -1.4993519783020020e+000
750 | 7
751 | -1
752 | <_>
753 |
754 |
755 | <_>
756 |
757 | <_>
758 |
759 |
760 |
761 | <_>
762 | 56 9 6 6 -1.
763 | <_>
764 | 59 9 3 6 2.
765 | 0
766 | -1.1395259760320187e-002
767 | 7.1383631229400635e-001
768 | -8.7429678440093994e-001
769 | <_>
770 |
771 | <_>
772 |
773 |
774 |
775 | <_>
776 | 6 4 1 6 -1.
777 | <_>
778 | 6 7 1 3 2.
779 | 0
780 | -2.1864590235054493e-003
781 | 8.5311782360076904e-001
782 | -6.4777731895446777e-001
783 | <_>
784 |
785 | <_>
786 |
787 |
788 |
789 | <_>
790 | 0 0 12 4 -1.
791 | <_>
792 | 0 0 6 2 2.
793 | <_>
794 | 6 2 6 2 2.
795 | 0
796 | 2.3193720262497663e-003
797 | -7.6411879062652588e-001
798 | 7.1867972612380981e-001
799 | <_>
800 |
801 | <_>
802 |
803 |
804 |
805 | <_>
806 | 43 12 18 2 -1.
807 | <_>
808 | 52 12 9 2 2.
809 | 0
810 | -7.9916073009371758e-003
811 | 6.6442942619323730e-001
812 | -7.9540950059890747e-001
813 | <_>
814 |
815 | <_>
816 |
817 |
818 |
819 | <_>
820 | 9 5 2 8 -1.
821 | <_>
822 | 10 5 1 8 2.
823 | 0
824 | 1.4212740352377295e-003
825 | -6.3904231786727905e-001
826 | 7.5050598382949829e-001
827 | -8.4829801321029663e-001
828 | 8
829 | -1
830 | <_>
831 |
832 |
833 | <_>
834 |
835 | <_>
836 |
837 |
838 |
839 | <_>
840 | 1 9 6 3 -1.
841 | <_>
842 | 3 9 2 3 3.
843 | 0
844 | 6.4091659151017666e-003
845 | -8.8425230979919434e-001
846 | 9.9953681230545044e-001
847 | <_>
848 |
849 | <_>
850 |
851 |
852 |
853 | <_>
854 | 56 8 2 8 -1.
855 | <_>
856 | 56 12 2 4 2.
857 | 0
858 | -6.3316390151157975e-004
859 | 8.3822172880172729e-001
860 | -9.8322170972824097e-001
861 | <_>
862 |
863 | <_>
864 |
865 |
866 |
867 | <_>
868 | 24 2 6 13 -1.
869 | <_>
870 | 26 2 2 13 3.
871 | 0
872 | -6.4947169448714703e-005
873 | 1.
874 | -9.1822808980941772e-001
875 | <_>
876 |
877 | <_>
878 |
879 |
880 |
881 | <_>
882 | 33 7 24 4 -1.
883 | <_>
884 | 41 7 8 4 3.
885 | 0
886 | 5.3404141217470169e-003
887 | -9.4317251443862915e-001
888 | 9.0425151586532593e-001
889 | -6.0007210820913315e-002
890 | 9
891 | -1
892 | <_>
893 |
894 |
895 | <_>
896 |
897 | <_>
898 |
899 |
900 |
901 | <_>
902 | 1 1 57 4 -1.
903 | <_>
904 | 1 3 57 2 2.
905 | 0
906 | 1.0755469650030136e-001
907 | -7.1647202968597412e-001
908 | 8.7827038764953613e-001
909 | <_>
910 |
911 | <_>
912 |
913 |
914 |
915 | <_>
916 | 0 2 6 14 -1.
917 | <_>
918 | 3 2 3 14 2.
919 | 0
920 | 3.1668949872255325e-002
921 | -8.7051069736480713e-001
922 | 5.8807212114334106e-001
923 | <_>
924 |
925 | <_>
926 |
927 |
928 |
929 | <_>
930 | 52 3 6 10 -1.
931 | <_>
932 | 54 3 2 10 3.
933 | 0
934 | -1.0572380386292934e-002
935 | 6.2438100576400757e-001
936 | -7.4027371406555176e-001
937 | <_>
938 |
939 | <_>
940 |
941 |
942 |
943 | <_>
944 | 1 14 61 2 -1.
945 | <_>
946 | 1 15 61 1 2.
947 | 0
948 | -2.7396259829401970e-002
949 | 8.9776748418807983e-001
950 | -5.2986758947372437e-001
951 | <_>
952 |
953 | <_>
954 |
955 |
956 |
957 | <_>
958 | 28 0 11 12 -1.
959 | <_>
960 | 28 4 11 4 3.
961 | 0
962 | 2.5918649509549141e-002
963 | -8.6482518911361694e-001
964 | 5.3121817111968994e-001
965 | -9.6125108003616333e-001
966 | 10
967 | -1
968 | <_>
969 |
970 |
971 | <_>
972 |
973 | <_>
974 |
975 |
976 |
977 | <_>
978 | 22 1 41 4 -1.
979 | <_>
980 | 22 3 41 2 2.
981 | 0
982 | 7.1039132773876190e-002
983 | -7.5719678401947021e-001
984 | 7.5645631551742554e-001
985 | <_>
986 |
987 | <_>
988 |
989 |
990 |
991 | <_>
992 | 41 6 6 8 -1.
993 | <_>
994 | 43 6 2 8 3.
995 | 0
996 | 7.6241148635745049e-003
997 | -7.9783838987350464e-001
998 | 7.1733069419860840e-001
999 | <_>
1000 |
1001 | <_>
1002 |
1003 |
1004 |
1005 | <_>
1006 | 50 9 14 5 -1.
1007 | <_>
1008 | 57 9 7 5 2.
1009 | 0
1010 | -2.7092639356851578e-002
1011 | 6.0071170330047607e-001
1012 | -8.4794402122497559e-001
1013 | <_>
1014 |
1015 | <_>
1016 |
1017 |
1018 |
1019 | <_>
1020 | 4 1 12 5 -1.
1021 | <_>
1022 | 10 1 6 5 2.
1023 | 0
1024 | -8.1267888890579343e-004
1025 | 5.9364068508148193e-001
1026 | -8.9295238256454468e-001
1027 | <_>
1028 |
1029 | <_>
1030 |
1031 |
1032 |
1033 | <_>
1034 | 37 9 3 3 -1.
1035 | <_>
1036 | 38 9 1 3 3.
1037 | 0
1038 | 8.3705072756856680e-004
1039 | -6.4887362718582153e-001
1040 | 7.8537952899932861e-001
1041 | -1.0618970394134521e+000
1042 | 11
1043 | -1
1044 | <_>
1045 |
1046 |
1047 | <_>
1048 |
1049 | <_>
1050 |
1051 |
1052 |
1053 | <_>
1054 | 54 0 10 6 -1.
1055 | <_>
1056 | 54 0 5 3 2.
1057 | <_>
1058 | 59 3 5 3 2.
1059 | 0
1060 | -9.7556859254837036e-003
1061 | 7.6982218027114868e-001
1062 | -8.5293501615524292e-001
1063 | <_>
1064 |
1065 | <_>
1066 |
1067 |
1068 |
1069 | <_>
1070 | 47 0 6 11 -1.
1071 | <_>
1072 | 49 0 2 11 3.
1073 | 0
1074 | -8.6617246270179749e-003
1075 | 8.4029090404510498e-001
1076 | -7.1949690580368042e-001
1077 | <_>
1078 |
1079 | <_>
1080 |
1081 |
1082 |
1083 | <_>
1084 | 19 2 20 2 -1.
1085 | <_>
1086 | 19 3 20 1 2.
1087 | 0
1088 | 1.6897840425372124e-002
1089 | -5.3601992130279541e-001
1090 | 9.5484441518783569e-001
1091 | <_>
1092 |
1093 | <_>
1094 |
1095 |
1096 |
1097 | <_>
1098 | 14 4 6 11 -1.
1099 | <_>
1100 | 17 4 3 11 2.
1101 | 0
1102 | 4.7526158596156165e-005
1103 | -7.6412862539291382e-001
1104 | 7.5398761034011841e-001
1105 | <_>
1106 |
1107 | <_>
1108 |
1109 |
1110 |
1111 | <_>
1112 | 31 9 33 2 -1.
1113 | <_>
1114 | 42 9 11 2 3.
1115 | 0
1116 | 6.5607670694589615e-003
1117 | -9.9346441030502319e-001
1118 | 6.4864277839660645e-001
1119 | -7.3307347297668457e-001
1120 | 12
1121 | -1
1122 | <_>
1123 |
1124 |
1125 | <_>
1126 |
1127 | <_>
1128 |
1129 |
1130 |
1131 | <_>
1132 | 6 1 53 6 -1.
1133 | <_>
1134 | 6 3 53 2 3.
1135 | 0
1136 | 1.0103269666433334e-001
1137 | -7.3275578022003174e-001
1138 | 8.4619927406311035e-001
1139 | <_>
1140 |
1141 | <_>
1142 |
1143 |
1144 |
1145 | <_>
1146 | 49 9 4 6 -1.
1147 | <_>
1148 | 49 9 2 3 2.
1149 | <_>
1150 | 51 12 2 3 2.
1151 | 0
1152 | -2.8920811018906534e-004
1153 | 7.1564781665802002e-001
1154 | -8.8221758604049683e-001
1155 | <_>
1156 |
1157 | <_>
1158 |
1159 |
1160 |
1161 | <_>
1162 | 0 9 30 7 -1.
1163 | <_>
1164 | 10 9 10 7 3.
1165 | 0
1166 | 1.0838840156793594e-002
1167 | -8.7420248985290527e-001
1168 | 6.0648679733276367e-001
1169 | <_>
1170 |
1171 | <_>
1172 |
1173 |
1174 |
1175 | <_>
1176 | 40 4 6 2 -1.
1177 | <_>
1178 | 42 4 2 2 3.
1179 | 0
1180 | 5.0803890917450190e-004
1181 | -9.0554022789001465e-001
1182 | 6.4213967323303223e-001
1183 | <_>
1184 |
1185 | <_>
1186 |
1187 |
1188 |
1189 | <_>
1190 | 1 9 6 1 -1.
1191 | <_>
1192 | 3 9 2 1 3.
1193 | 0
1194 | 2.3357039317488670e-003
1195 | -9.2574918270111084e-001
1196 | 8.6384928226470947e-001
1197 | <_>
1198 |
1199 | <_>
1200 |
1201 |
1202 |
1203 | <_>
1204 | 47 3 4 10 -1.
1205 | <_>
1206 | 47 8 4 5 2.
1207 | 0
1208 | 8.0239427916239947e-005
1209 | -9.9618428945541382e-001
1210 | 9.5355111360549927e-001
1211 | <_>
1212 |
1213 | <_>
1214 |
1215 |
1216 |
1217 | <_>
1218 | 31 5 30 11 -1.
1219 | <_>
1220 | 41 5 10 11 3.
1221 | 0
1222 | 3.2030208967626095e-003
1223 | -1.
1224 | 1.0001050233840942e+000
1225 | <_>
1226 |
1227 | <_>
1228 |
1229 |
1230 |
1231 | <_>
1232 | 0 0 2 1 -1.
1233 | <_>
1234 | 1 0 1 1 2.
1235 | 0
1236 | 0.
1237 | 0.
1238 | -1.
1239 | <_>
1240 |
1241 | <_>
1242 |
1243 |
1244 |
1245 | <_>
1246 | 21 3 42 5 -1.
1247 | <_>
1248 | 35 3 14 5 3.
1249 | 0
1250 | 2.6143440045416355e-003
1251 | -1.
1252 | 1.0002139806747437e+000
1253 | <_>
1254 |
1255 | <_>
1256 |
1257 |
1258 |
1259 | <_>
1260 | 0 0 2 1 -1.
1261 | <_>
1262 | 1 0 1 1 2.
1263 | 0
1264 | 0.
1265 | 0.
1266 | -1.
1267 | <_>
1268 |
1269 | <_>
1270 |
1271 |
1272 |
1273 | <_>
1274 | 8 5 30 9 -1.
1275 | <_>
1276 | 8 8 30 3 3.
1277 | 0
1278 | -7.0475979009643197e-004
1279 | 1.
1280 | -9.9976968765258789e-001
1281 | <_>
1282 |
1283 | <_>
1284 |
1285 |
1286 |
1287 | <_>
1288 | 3 12 33 3 -1.
1289 | <_>
1290 | 14 12 11 3 3.
1291 | 0
1292 | 2.1271279547363520e-003
1293 | -9.9694627523422241e-001
1294 | 1.0002720355987549e+000
1295 | <_>
1296 |
1297 | <_>
1298 |
1299 |
1300 |
1301 | <_>
1302 | 0 0 3 2 -1.
1303 | <_>
1304 | 1 0 1 2 3.
1305 | 0
1306 | -2.4224430671893060e-004
1307 | 1.
1308 | -1.
1309 | <_>
1310 |
1311 | <_>
1312 |
1313 |
1314 |
1315 | <_>
1316 | 46 4 3 8 -1.
1317 | <_>
1318 | 47 4 1 8 3.
1319 | 0
1320 | 7.4700301047414541e-004
1321 | -9.9108231067657471e-001
1322 | 9.9941182136535645e-001
1323 | -1.0991690158843994e+000
1324 | 13
1325 | -1
1326 | <_>
1327 |
1328 |
1329 | <_>
1330 |
1331 | <_>
1332 |
1333 |
1334 |
1335 | <_>
1336 | 1 2 6 5 -1.
1337 | <_>
1338 | 3 2 2 5 3.
1339 | 0
1340 | 1.7227890202775598e-003
1341 | -9.3608891963958740e-001
1342 | 8.7251222133636475e-001
1343 | <_>
1344 |
1345 | <_>
1346 |
1347 |
1348 |
1349 | <_>
1350 | 0 3 18 5 -1.
1351 | <_>
1352 | 6 3 6 5 3.
1353 | 0
1354 | 2.7599320746958256e-003
1355 | -9.9757021665573120e-001
1356 | 1.0000289678573608e+000
1357 | <_>
1358 |
1359 | <_>
1360 |
1361 |
1362 |
1363 | <_>
1364 | 3 1 6 14 -1.
1365 | <_>
1366 | 6 1 3 14 2.
1367 | 0
1368 | -8.9444358309265226e-005
1369 | 1.
1370 | -9.9264812469482422e-001
1371 | <_>
1372 |
1373 | <_>
1374 |
1375 |
1376 |
1377 | <_>
1378 | 3 6 2 10 -1.
1379 | <_>
1380 | 3 11 2 5 2.
1381 | 0
1382 | -2.7962020249105990e-004
1383 | 8.2833290100097656e-001
1384 | -9.8444151878356934e-001
1385 | <_>
1386 |
1387 | <_>
1388 |
1389 |
1390 |
1391 | <_>
1392 | 42 0 4 6 -1.
1393 | <_>
1394 | 42 0 2 3 2.
1395 | <_>
1396 | 44 3 2 3 2.
1397 | 0
1398 | -2.7560539820115082e-005
1399 | 1.
1400 | -9.9543339014053345e-001
1401 | -9.1314977407455444e-001
1402 | 14
1403 | -1
1404 |
1405 |
--------------------------------------------------------------------------------
/3_face_detection/code/3.1_face_detection.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 |
7 | created on 08:29:27 2018-11-16
8 |
9 | @author:ren_dong
10 |
11 | haar级联分类器实现静态图像人脸检测
12 |
13 | 1、准备人脸、非人脸样本集;
14 |
15 | 2、计算特征值和积分图;
16 |
17 | 3、筛选出T个优秀的特征值(即最优弱分类器);
18 |
19 | 4、把这个T个最优弱分类器传给AdaBoost进行训练。
20 |
21 | 5、级联,也就是强分类器的强强联手。
22 |
23 | cv2.CascadeClassifier([filename]) →
24 |
25 | cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) → objects
26 |
27 | '''
28 | filename = './images/face1.jpg'
29 |
30 | def detect(filename):
31 |
32 | #声明face_cascade对象,该变量为cascadeclassifier对象,它负责人脸检测
33 | face_cascade = cv2.CascadeClassifier('./cascade/haarcascade_frontalface_default.xml')
34 |
35 | img= cv2.imread(filename)
36 |
37 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
38 |
39 |
40 | # 进行人脸检测,传入scaleFactor,minNegihbors,分别表示人脸检测过程中每次迭代时图像的压缩率以及
41 | # 每个人脸矩形保留近似数目的最小值
42 |
43 | # 返回人脸矩形数组
44 | face = face_cascade.detectMultiScale(gray, 1.3, 5)
45 |
46 | for (x, y, w, h) in face:
47 |
48 | #绘制矩形
49 | img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2 )
50 |
51 | #创建窗口
52 | cv2.namedWindow('face_detection')
53 |
54 | cv2.imshow('face_detection', img)
55 |
56 | cv2.waitKey()
57 |
58 | cv2.destroyAllWindows()
59 |
60 |
61 | if __name__ == '__main__':
62 | detect(filename)
--------------------------------------------------------------------------------
/3_face_detection/code/3.2_face_video.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 |
5 | '''
6 |
7 | created on 19:18:27 2018-11-16
8 |
9 | @author:ren_dong
10 |
11 | haar级联分类器实现视频中的人脸检测
12 |
13 | 打开摄像头,读取帧,检测帧中的人脸,扫描检测到的人脸中的眼睛,对人脸绘制蓝色的矩形框,对人眼绘制绿色的矩形框
14 |
15 |
16 | cv2.CascadeClassifier([filename]) →
17 |
18 | cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]
19 |
20 |
21 | '''
22 |
23 |
24 | def DynamicDetect():
25 |
26 | # 创建一个级联分类器 加载一个 .xml 分类器文件. 它既可以是Haar特征也可以是LBP特征的分类器.
27 | face_cascade = cv2.CascadeClassifier('./cascade/haarcascade_frontalface_default.xml')
28 |
29 | eye_cascade = cv2.CascadeClassifier('./cascade/haarcascade_eye.xml')
30 |
31 | # 打开摄像头
32 | camera = cv2.VideoCapture(0)
33 | cv2.namedWindow('Dynamic')
34 |
35 | while (True):
36 | # 读取一帧图像
37 | ret, frame = camera.read()
38 | # 判断图片读取成功?
39 | #rect()函数会返回两个值,第一个值是布尔值,用来表明是否成功读取帧,第二个为帧本身
40 | if ret:
41 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
42 | # 人脸检测
43 | faces = face_cascade.detectMultiScale(gray, 1.3, 5)
44 | for (x, y, w, h) in faces:
45 | # 在原图像上绘制矩形
46 | cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
47 | roi_gray = gray[y:y + h, x:x + w]
48 | # 眼睛检测
49 | eyes = eye_cascade.detectMultiScale(roi_gray, 1.03, 5, 0, (40, 40))
50 | for (ex, ey, ew, eh) in eyes:
51 | cv2.rectangle(frame, (ex + x, ey + y), (x + ex + ew, y + ey + eh), (0, 255, 0), 2)
52 |
53 | cv2.imshow('Dynamic', frame)
54 | # 如果按下q键则退出
55 | if cv2.waitKey(100) & 0xff == ord('q'):
56 | break
57 |
58 | camera.release()
59 | cv2.destroyAllWindows()
60 |
61 |
62 | if __name__ == '__main__':
63 | # filename = './image/img23.jpg'
64 | # StaticDetect(filename)
65 | DynamicDetect()
66 |
67 |
--------------------------------------------------------------------------------
/3_face_detection/code/3.3.1_face_recognition.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | import os
5 | '''
6 |
7 | created on 10:24:27 2018-11-18
8 |
9 | @author:ren_dong
10 |
11 | 人脸识别 调用摄像头进行个人头像数据采集,作为数据库
12 |
13 | 只是在原来检测人脸目标框的基础上,添加了resize()函数进行图像的resize,
14 | 然后调用imwrite()函数进行保存到指定路径下
15 |
16 | '''
17 |
18 | def Generate_name():
19 |
20 | # data = input('data:')
21 | #
22 | # name = input('input your name:')
23 | #
24 | # path = os.path.join(data, name)
25 | #
26 | # if os.path.isdir(path):
27 | # os.remove(path)
28 | # os.removedirs(path)
29 |
30 | #
31 | # os.mkdir(path)
32 |
33 | face_cascade = cv2.CascadeClassifier('./cascade/haarcascade_frontalface_default.xml')
34 |
35 | camera = cv2.VideoCapture(0)
36 | cv2.namedWindow('myself')
37 | count = 1
38 |
39 | while(True):
40 |
41 | ret, frame = camera.read()
42 |
43 | if ret:
44 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
45 |
46 | faces = cv2.CascadeClassifier.detectMultiScale(face_cascade, gray, 1.3, 5)
47 |
48 | for (x, y, w, h) in faces:
49 | cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
50 |
51 | f = cv2.resize(gray[y:y+h, x:x+w], (92, 112))
52 |
53 | cv2.imwrite('./data/ren_dong/%s.pgm' % str(count), f)
54 |
55 | count += 1
56 |
57 | cv2.imshow('myself', frame)
58 |
59 | if cv2.waitKey(35) & 0xff == ord('q'):
60 | break
61 |
62 | camera.release()
63 | cv2.destroyAllWindows()
64 |
65 | if __name__ == '__main__':
66 | Generate_name()
--------------------------------------------------------------------------------
/3_face_detection/code/3.3.2_trainset.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | import os
5 |
6 | '''
7 |
8 | created on 10:24:27 2018-11-18
9 |
10 | @author:ren_dong
11 |
12 | 人脸识别
13 | 利用数据进行数据集制作
14 |
15 | '''
16 |
17 |
18 | # 2、读取ORL人脸数据库 准备训练数据
19 | def LoadImages(data):
20 | '''
21 | 加载数据集
22 | params:
23 | data:训练集数据所在的目录,要求数据尺寸大小一样
24 | ret:
25 | images:[m,height,width] m为样本数,height为高,width为宽
26 | names:名字的集合
27 | labels:标签
28 | '''
29 | images = []
30 | labels = []
31 | names = []
32 |
33 | label = 0
34 | # 过滤所有的文件夹
35 | for subDirname in os.listdir(data):
36 |
37 | subjectPath = os.path.join(data, subDirname)
38 | #subjectpath即每一类所在的文件夹
39 | if os.path.isdir(subjectPath):
40 | # 每一个文件夹下存放着一个人的照片
41 | names.append(subDirname)
42 | ##得到图片名字filename
43 |
44 | for fileName in os.listdir(subjectPath):
45 | #路径拼接,得到图片路径
46 | imgPath = os.path.join(subjectPath, fileName)
47 | #遍历路径按照文件名 读取图片
48 | img = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE)
49 | #添加images
50 | images.append(img)
51 | #添加label
52 | labels.append(label)
53 | label += 1
54 | images = np.asarray(images)
55 | labels = np.asarray(labels)
56 | return images, labels, names
57 |
58 |
59 | if __name__ == '__main__':
60 | data = './data'
61 | LoadImages(data)
--------------------------------------------------------------------------------
/3_face_detection/code/3.3.3_recognition.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import cv2
3 | import numpy as np
4 | import os
5 | import shutil
6 |
7 | '''
8 |
9 | created on 10:24:27 2018-11-18
10 |
11 | @author:ren_dong
12 |
13 | 人脸识别 调用摄像头进行个人头像数据采集,作为数据库
14 |
15 | 只是在原来检测人脸目标框的基础上,添加了resize()函数进行图像的resize,
16 | 然后调用imwrite()函数进行保存到指定路径下
17 |
18 | '''
19 |
20 | # -*- coding: utf-8 -*-
21 | """
22 | Created on Thu Aug 16 19:41:19 2018
23 |
24 | @author: lenovo
25 | """
26 |
27 | '''
28 | 调用opencv库实现人脸识别
29 | '''
30 |
31 | # 读取pgm图像,并显示
32 | def ShowPgm(filepath):
33 | cv2.namedWindow('pgm')
34 | img = cv2.imread(filepath)
35 | cv2.imshow('pgm', img)
36 | print(img.shape)
37 | cv2.waitKey(0)
38 | cv2.destroyAllWindows()
39 |
40 | # 2、读取ORL人脸数据库 准备训练数据
41 | def LoadImages(data):
42 | '''
43 | 加载数据集
44 | params:
45 | data:训练集数据所在的目录,要求数据尺寸大小一样
46 | ret:
47 | images:[m,height,width] m为样本数,height为高,width为宽
48 | names:名字的集合
49 | labels:标签
50 | '''
51 | images = []
52 | labels = []
53 | names = []
54 |
55 | label = 0
56 | # 过滤所有的文件夹
57 | for subDirname in os.listdir(data):
58 |
59 | subjectPath = os.path.join(data, subDirname)
60 | #subjectpath即每一类所在的文件夹
61 | if os.path.isdir(subjectPath):
62 | # 每一个文件夹下存放着一个人的照片
63 | names.append(subDirname)
64 | ##得到图片名字filename
65 |
66 | for fileName in os.listdir(subjectPath):
67 | #路径拼接,得到图片路径
68 | imgPath = os.path.join(subjectPath, fileName)
69 | #遍历路径按照文件名 读取图片
70 | img = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE)
71 | #添加images
72 | images.append(img)
73 | #添加label
74 | labels.append(label)
75 | label += 1
76 | images = np.asarray(images)
77 | labels = np.asarray(labels)
78 | return images, labels, names
79 |
80 |
81 | def FaceRec(data):
82 | # 加载训练数据
83 | X, y, names = LoadImages('./data')
84 |
85 |
86 | model = cv2.face.EigenFaceRecognizer_create()
87 | model.train(X, y)
88 |
89 | # 创建一个级联分类器 加载一个 .xml 分类器文件. 它既可以是Haar特征也可以是LBP特征的分类器.
90 | face_cascade = cv2.CascadeClassifier('./cascade/haarcascade_frontalface_default.xml')
91 |
92 | # 打开摄像头
93 | camera = cv2.VideoCapture(0)
94 | cv2.namedWindow('Dynamic')
95 |
96 | while (True):
97 | # 读取一帧图像
98 | ret, frame = camera.read()
99 | # 判断图片读取成功?
100 | if ret:
101 | gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
102 | # 人脸检测
103 |
104 | faces = face_cascade.detectMultiScale(gray_img, 1.3, 5)
105 | for (x, y, w, h) in faces:
106 | # 在原图像上绘制矩形
107 | frame = cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
108 | roi_gray = gray_img[y:y + h, x:x + w]
109 |
110 | try:
111 | # 宽92 高112
112 | roi_gray = cv2.resize(roi_gray, (92, 112), interpolation=cv2.INTER_LINEAR)
113 | params = model.predict(roi_gray)
114 | print('Label:%s,confidence:%.2f' % (params[0], params[1]))
115 | cv2.putText(frame, names[params[0]], (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
116 | except:
117 | continue
118 |
119 | cv2.imshow('Dynamic', frame)
120 | # 如果按下q键则退出
121 | if cv2.waitKey(100) & 0xff == ord('q'):
122 | break
123 | camera.release()
124 | cv2.destroyAllWindows()
125 |
126 |
127 | if __name__ == '__main__':
128 | # ShowPgm('./face/s1/1.pgm')
129 | data = './data'
130 | # 生成自己的人脸数据
131 | # generator(data)
132 | FaceRec(data)
--------------------------------------------------------------------------------
/3_face_detection/code/Readme:
--------------------------------------------------------------------------------
1 | The code stores the program that calls the Haar classifier for face detection,
2 |
3 | including detecting face detection in still images and videos.
4 |
--------------------------------------------------------------------------------
/3_face_detection/data/S1/1.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/1.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/10.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/10.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/2.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/2.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/3.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/3.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/4.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/4.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/5.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/5.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/6.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/6.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/7.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/7.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/8.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/8.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/9.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/data/S1/9.pgm
--------------------------------------------------------------------------------
/3_face_detection/data/S1/Readme:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/3_face_detection/data/ren_dong/Readme:
--------------------------------------------------------------------------------
1 | This store is a personal picture, a total of ten, suffixed with .pgm
2 |
--------------------------------------------------------------------------------
/3_face_detection/images/Readme:
--------------------------------------------------------------------------------
1 | Images store test images for static face detection
2 |
--------------------------------------------------------------------------------
/3_face_detection/images/face1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/images/face1.jpg
--------------------------------------------------------------------------------
/3_face_detection/images/face2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/images/face2.jpg
--------------------------------------------------------------------------------
/3_face_detection/output/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/3_face_detection/output/1.png
--------------------------------------------------------------------------------
/4_Feature matching/code/4.1_Harris.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import os
3 | import cv2
4 | import numpy as np
5 | '''
6 | created on 08:05:10 2018-11-20
7 | @author ren_dong
8 |
9 | 使用cornerHarris进行角点检测
10 |
11 | cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]]) → dst
12 |
13 |
14 | '''
15 | img = cv2.imread('chess.jpg')
16 |
17 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
18 |
19 | gray= np.float32(gray)
20 |
21 | #第三个参数定义了角点检测的敏感度,其值必须是介于3和31之间的奇数
22 | ##dst为函数返回的浮点值图像,其中包含角点检测结果
23 | #第二个参数值决定了标记角点的记号大小,参数值越小,记号越小
24 | dst = cv2.cornerHarris(gray, 4, 23, 0.04)
25 | print dst.shape
26 | #在原图进行标记 阈值
27 | img[dst > 0.01*dst.max()] = [0, 0, 255]
28 |
29 | while(True):
30 |
31 | cv2.imshow('Harris', img)
32 | if cv2.waitKey(100) & 0xff == ord('q'):
33 | break
34 |
35 | cv2.destroyAllWindows()
36 |
--------------------------------------------------------------------------------
/4_Feature matching/code/4.2_SIFT.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import os
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | created on 08:05:10 2018-11-20
8 | @author ren_dong
9 |
10 | 使用DoG和SIFT进行特征提取和描述
11 |
12 | cv2.SIFT.detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]]) → keypoints, descriptors
13 |
14 | cv2.drawKeypoints(image, keypoints[, outImage[, color[, flags]]]) → outImage
15 |
16 | 首先创建了一个SIFT对象,SIFT对象会使用DoG检测关键点,并且对每个关键点周围区域计算特征向量。
17 | detectAndCompute()函数会返回关键点信息(每一个元素都是一个对象,有兴趣的可以看一下OpenCV源码)和关键点的描述符。
18 | 然后,我们在图像上绘制关键点,并显示出来。
19 |
20 | '''
21 | img = cv2.imread('chess.jpg')
22 |
23 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
24 |
25 | #创建sift对象
26 | sift = cv2.xfeatures2d.SIFT_create()
27 |
28 | #进行检测和计算 返回特征点信息和描述符
29 | keypoints , descriptor = sift.detectAndCompute(gray, None)
30 | #keypoints:特征点集合list,向量内每一个元素是一个KeyPoint对象,包含了特征点的各种属性信息;
31 |
32 |
33 |
34 | #绘制关键点
35 | img = cv2.drawKeypoints(img, keypoints=keypoints, outImage=img, color= (51, 163, 236), flags= cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
36 |
37 | #sift得到的图像为128维的特征向量集
38 |
39 | print len(keypoints)
40 | print descriptor.shape
41 |
42 | cv2.imshow('sift_keypoints',img)
43 | cv2.waitKey()
44 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/4_Feature matching/code/4.3_SURF.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import os
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | created on 09:05:10 2018-11-22
8 | @author ren_dong
9 |
10 | 使用快速Hessian算法和SURF来提取和检测特征
11 |
12 | '''
13 | img = cv2.imread('chess.jpg')
14 |
15 | gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
16 |
17 | #创建一个SURF对象
18 | surf = cv2.xfeatures2d.SURF_create(20000)
19 | #SURF算法使用Hessian算法计算关键点,并且在关键点周围区域计算特征向量,该函数返回关键点的信息和描述符
20 | keypoints, descriptor = surf.detectAndCompute(gray, None)
21 | print descriptor.shape
22 | print len(keypoints)
23 |
24 | img = cv2.drawKeypoints(image=img, outImage=img, keypoints=keypoints, flags=4, color=(51, 163, 236))
25 |
26 | cv2.imshow('SURF', img)
27 |
28 | cv2.waitKey()
29 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/4_Feature matching/code/4.4_fast.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Mon Aug 27 16:09:48 2018
4 |
5 | @author: lenovo
6 | """
7 |
8 | '''
9 | FAST角点检测
10 | '''
11 | import cv2
12 |
13 | '''1、加载图片'''
14 | img1 = cv2.imread('chess.jpg')
15 | img1 = cv2.resize(img1,dsize=(600,400))
16 | image1 = img1.copy()
17 |
18 |
19 | '''2、提取特征点'''
20 | #创建一个FAST对象,传入阈值t 可以处理RGB色彩空间图像
21 | fast = cv2.FastFeatureDetector_create(threshold=50)
22 | keypoints1 = fast.detect(image1,None)
23 | #在图像上绘制关键点
24 | image1 = cv2.drawKeypoints(image=image1,keypoints = keypoints1,outImage=image1,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
25 |
26 | #输出默认参数
27 | print("Threshold: ", fast.getThreshold())
28 | print("nonmaxSuppression: ", fast.getNonmaxSuppression())
29 | print("neighborhood: ", fast.getType())
30 | print("Total Keypoints with nonmaxSuppression: ", len(keypoints1))
31 |
32 | #显示图像
33 | cv2.imshow('fast_keypoints1',image1)
34 | cv2.waitKey(20)
35 |
36 | #关闭非极大值抑制
37 | fast.setNonmaxSuppression(0)
38 | keypoints1 = fast.detect(image1,None)
39 | print("Total Keypoints without nonmaxSuppression: ", len(keypoints1))
40 | image1 = cv2.drawKeypoints(image=image1,keypoints = keypoints1,outImage=image1,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
41 | cv2.imshow('fast_keypoints1 nms',image1)
42 |
43 | cv2.waitKey(0)
44 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/4_Feature matching/code/4.5_ORB.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import os
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | created on 09:05:10 2018-11-22
8 | @author ren_dong
9 |
10 | 使用ORB特征匹配
11 |
12 | '''
13 | def orb_test():
14 | # 加载图片 灰色
15 | img1 = cv2.imread('orb1.jpg')
16 | gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
17 | img2 = cv2.imread('orb2.jpg')
18 | img2 = cv2.resize(img2, dsize=(450, 300))
19 | gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
20 | image1 = gray1.copy()
21 | image2 = gray2.copy()
22 |
23 | '''
24 | 1.使用ORB算法检测特征点、描述符
25 | '''
26 | orb = cv2.ORB_create(128)
27 | keypoints1, descriptors1 = orb.detectAndCompute(image1, None)
28 | keypoints2, descriptors2 = orb.detectAndCompute(image2, None)
29 | # 在图像上绘制关键点
30 | image1 = cv2.drawKeypoints(image=image1, keypoints=keypoints1, outImage=image1, color=(255, 0, 255),
31 | flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
32 | image2 = cv2.drawKeypoints(image=image2, keypoints=keypoints2, outImage=image2, color=(255, 0, 255),
33 | flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
34 | # 显示图像
35 | cv2.imshow('orb_keypoints1', image1)
36 | cv2.imshow('orb_keypoints2', image2)
37 | cv2.waitKey(20)
38 |
39 | '''
40 | 2、匹配
41 | '''
42 | matcher = cv2.BFMatcher_create(cv2.HAMMING_NORM_TYPE, crossCheck=True)
43 | matchePoints = matcher.match(descriptors1, descriptors2)
44 | print(type(matchePoints), len(matchePoints), matchePoints[0])
45 | # 按照距离从小到大排序,选取最优匹配的
46 | sorted(matchePoints, key=lambda x: x.distance)
47 | # 绘制最优匹配点
48 | outImg = None
49 | outImg = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matchePoints[:40], outImg, matchColor=(0, 255, 0),
50 | flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT)
51 | cv2.imshow('matche', outImg)
52 | cv2.waitKey(0)
53 | cv2.destroyAllWindows()
54 |
55 | cv2.waitKey(0)
56 | cv2.destroyAllWindows()
57 |
58 |
59 | if __name__ == '__main__':
60 | orb_test()
--------------------------------------------------------------------------------
/4_Feature matching/code/4.6_KNN.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import os
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | created on 09:05:10 2018-11-22
8 | @author ren_dong
9 |
10 | 使用KNN即K近邻算法进行特征匹配
11 | ORB算法
12 |
13 | '''
14 |
15 | img1 = cv2.imread('orb1.jpg',0) #测试图像img1
16 | # img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
17 | img2 = cv2.imread('orb2.jpg',0) ##训练图像img2
18 | # img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
19 |
20 | orb = cv2.ORB_create()
21 | kp1, des1 = orb.detectAndCompute(img1, None)
22 | kp2, des2 = orb.detectAndCompute(img2, None)
23 |
24 | bf = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck = False)
25 | #对每个匹配选择两个最佳的匹配
26 | matches = bf.knnMatch(des1, des2, k=2)
27 |
28 | print(type(matches), len(matches), matches[0])
29 |
30 | # 获取img1中的第一个描述符即[0][]在img2中最匹配即[0][0]的一个描述符 距离最小
31 | dMatch0 = matches[0][0]
32 |
33 | # 获取img1中的第一个描述符在img2中次匹配的一个描述符 距离次之
34 | dMatch1 = matches[0][1]
35 | print('knnMatches', dMatch0.distance, dMatch0.queryIdx, dMatch0.trainIdx)
36 | print('knnMatches', dMatch1.distance, dMatch1.queryIdx, dMatch1.trainIdx)
37 | # 将不满足的最近邻的匹配之间距离比率大于设定的阈值匹配剔除。
38 |
39 | img3 = None
40 | img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, img3, flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT)
41 | img3 = cv2.resize(img3,(1000, 400))
42 | cv2.imshow('KNN',img3)
43 | cv2.waitKey()
44 | cv2.destroyAllWindows()
45 |
46 |
--------------------------------------------------------------------------------
/4_Feature matching/code/4.7_FLANN.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import os
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | created on 09:05:10 2018-11-22
8 | @author ren_dong
9 |
10 | 使用FLANN特征匹配
11 |
12 | '''
13 | def flann_test():
14 | '''
15 | FLANN匹配
16 | '''
17 | # 加载图片 灰色
18 | img1 = cv2.imread('orb1.jpg')
19 | gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
20 | img2 = cv2.imread('orb2.jpg')
21 | img2 = cv2.resize(img2, dsize=(450, 300))
22 | gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
23 | queryImage = gray1.copy()
24 | trainImage = gray2.copy()
25 |
26 | # 创建SIFT对象
27 | sift = cv2.xfeatures2d.SIFT_create(100)
28 | # SIFT对象会使用DoG检测关键点,并且对每个关键点周围的区域计算特征向量。该函数返回关键点的信息和描述符
29 | keypoints1, descriptor1 = sift.detectAndCompute(queryImage, None)
30 | keypoints2, descriptor2 = sift.detectAndCompute(trainImage, None)
31 | print('descriptor1:', descriptor1.shape, 'descriptor2', descriptor2.shape)
32 | # 在图像上绘制关键点
33 | queryImage = cv2.drawKeypoints(image=queryImage, keypoints=keypoints1, outImage=queryImage, color=(255, 0, 255),
34 | flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
35 | trainImage = cv2.drawKeypoints(image=trainImage, keypoints=keypoints2, outImage=trainImage, color=(255, 0, 255),
36 | flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
37 | # 显示图像
38 | # cv2.imshow('sift_keypoints1',queryImage)
39 | # cv2.imshow('sift_keypoints2',trainImage)
40 | # cv2.waitKey(20)
41 |
42 | # FLANN匹配
43 | FLANN_INDEX_KDTREE = 0
44 | indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
45 | searchParams = dict(checks=50)
46 | flann = cv2.FlannBasedMatcher(indexParams, searchParams)
47 | #indexParams, searchParams
48 | matches = flann.knnMatch(descriptor1, descriptor2, k=2)
49 |
50 | print(type(matches), len(matches), matches[0])
51 | # 获取queryImage中的第一个描述符在trainingImage中最匹配的一个描述符 距离最小
52 | dMatch0 = matches[0][0]
53 | # 获取queryImage中的第一个描述符在trainingImage中次匹配的一个描述符 距离次之
54 | dMatch1 = matches[0][1]
55 | print('knnMatches', dMatch0.distance, dMatch0.queryIdx, dMatch0.trainIdx)
56 | print('knnMatches', dMatch1.distance, dMatch1.queryIdx, dMatch1.trainIdx)
57 |
58 | # 设置mask,过滤匹配点 作用和上面那个一样
59 | matchesMask = [[0, 0] for i in range(len(matches))]
60 |
61 | minRatio = 1 / 3
62 | for i, (m, n) in enumerate(matches):
63 | if m.distance / n.distance < minRatio:
64 | matchesMask[i] = [1, 0] # 只绘制最优匹配点
65 |
66 | drawParams = dict( # singlePointColor=(255,0,0),matchColor=(0,255,0),
67 | matchesMask=matchesMask,
68 | flags=0)
69 | resultImage = cv2.drawMatchesKnn(queryImage, keypoints1, trainImage, keypoints2, matches,
70 | None, **drawParams)
71 |
72 | cv2.imshow('matche', resultImage)
73 | cv2.waitKey(0)
74 | cv2.destroyAllWindows()
75 |
76 |
77 | if __name__ == '__main__':
78 | flann_test()
--------------------------------------------------------------------------------
/4_Feature matching/code/4.8_danyingxing.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Sat Sep 15 13:22:10 2018
4 |
5 | @author: zy
6 | """
7 |
8 | '''
9 | 单应性匹配
10 | '''
11 |
12 | import numpy as np
13 | import cv2
14 |
15 |
16 | def flann_hom_test():
17 | # 加载图像
18 | img1 = cv2.imread('orb1.jpg') # queryImage
19 | img2 = cv2.imread('orb2.jpg') # trainImage
20 | gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
21 | gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
22 |
23 | # img2 = cv2.resize(img2,dsize=(450,600))
24 |
25 | MIN_MATCH_COUNT = 10
26 |
27 | '''
28 | 1.使用SIFT算法检测特征点、描述符
29 | '''
30 | sift = cv2.xfeatures2d.SIFT_create(100)
31 | kp1, des1 = sift.detectAndCompute(gray1, None)
32 | kp2, des2 = sift.detectAndCompute(gray2, None)
33 | # 在图像上绘制关键点
34 | # img1 = cv2.drawKeypoints(image=img1,keypoints = kp1,outImage=img1,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
35 | # img2 = cv2.drawKeypoints(image=img2,keypoints = kp2,outImage=img2,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
36 | # 显示图像
37 | # cv2.imshow('sift_keypoints1',img1)
38 | # cv2.imshow('sift_keypoints2',img2)
39 | # cv2.waitKey(20)
40 |
41 | '''
42 | 2、FLANN匹配
43 | '''
44 | FLANN_INDEX_KDTREE = 0
45 | indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
46 | searchParams = dict(checks=50)
47 | flann = cv2.FlannBasedMatcher(indexParams, searchParams)
48 | matches = flann.knnMatch(des1, des2, k=2)
49 |
50 | # 将不满足的最近邻的匹配之间距离比率大于设定的阈值匹配剔除。
51 | goodMatches = []
52 | minRatio = 0.7
53 | for m, n in matches:
54 | if m.distance / n.distance < minRatio:
55 | goodMatches.append(m) # 注意 如果使用drawMatches 则不用写成List类型[m]
56 |
57 | '''
58 | 3、单应性变换
59 | '''
60 | # 确保至少有一定数目的良好匹配(理论上,计算单应性至少需要4对匹配点,实际上会使用10对以上的匹配点)
61 | if len(goodMatches) > MIN_MATCH_COUNT:
62 | # 获取匹配点坐标
63 | src_pts = np.float32([kp1[m.queryIdx].pt for m in goodMatches]).reshape(-1, 2)
64 | dst_pts = np.float32([kp2[m.trainIdx].pt for m in goodMatches]).reshape(-1, 2)
65 |
66 | print('src_pts:', len(src_pts), src_pts[0])
67 | print('dst_pts:', len(dst_pts), dst_pts[0])
68 |
69 | # 获取单应性:即一个平面到另一个平面的映射矩阵
70 | M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
71 | # print('M:',M,type(M)) # [3,3]
72 | matchesMask = mask.ravel().tolist() # 用来配置匹配图,只绘制单应性图片中关键点的匹配线
73 | # 由于使用的是drawMatches绘制匹配线,这里list
74 | # 每个元素也是一个标量,并不是一个list
75 | print('matchesMask:', len(matchesMask), matchesMask[0])
76 |
77 | # 计算原始图像img1中书的四个顶点的投影畸变,并在目标图像img2上绘制边框
78 | h, w = img1.shape[:2]
79 | # 源图片中书的的四个角点
80 | pts = np.float32([[55, 74], [695, 45], [727, 464], [102, 548]]).reshape(-1, 1, 2)
81 | print('pts:', pts.shape)
82 | dst = cv2.perspectiveTransform(pts, M)
83 | print('dst:', dst.shape)
84 | # 在img2上绘制边框
85 | img2 = cv2.polylines(img2, [np.int32(dst)], True, (0, 255, 0), 2, cv2.LINE_AA)
86 |
87 | else:
88 | print("Not enough matches are found - %d/%d" % (len(goodMatches), MIN_MATCH_COUNT))
89 | matchesMask = None
90 |
91 | '''
92 | 绘制显示效果
93 | '''
94 | draw_params = dict(matchColor=(0, 255, 0), # draw matches in green color
95 | singlePointColor=None,
96 | matchesMask=matchesMask, # draw only inliers
97 | flags=2)
98 |
99 | img3 = cv2.drawMatches(img1, kp1, img2, kp2, goodMatches, None, **draw_params)
100 | cv2.imshow('matche', img3)
101 | cv2.waitKey(0)
102 | cv2.destroyAllWindows()
103 |
104 |
105 | if __name__ == '__main__':
106 | flann_hom_test()
--------------------------------------------------------------------------------
/4_Feature matching/code/readme:
--------------------------------------------------------------------------------
1 | This file is used to store the code
2 |
--------------------------------------------------------------------------------
/4_Feature matching/images/chess.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/4_Feature matching/images/chess.jpg
--------------------------------------------------------------------------------
/4_Feature matching/images/orb1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/4_Feature matching/images/orb1.jpg
--------------------------------------------------------------------------------
/4_Feature matching/images/orb2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/4_Feature matching/images/orb2.jpg
--------------------------------------------------------------------------------
/4_Feature matching/images/readme:
--------------------------------------------------------------------------------
1 | This file is used to store images
2 |
--------------------------------------------------------------------------------
/4_Feature matching/readme:
--------------------------------------------------------------------------------
1 | This chapter describes how to use opencv to detect image features
2 |
3 | and use these features for image matching and searching.
4 |
--------------------------------------------------------------------------------
/5_face_recognition/readme:
--------------------------------------------------------------------------------
1 | 记录自己对face_recognition 人脸识别库的简单应用
2 |
3 | 包括人脸绘制轮廓
4 |
5 |
6 |
7 |
8 |
9 | 提取图片人脸
10 |
11 |
12 |
13 |
14 | 美妆
15 |
--------------------------------------------------------------------------------
/5_object_detection/code/5.1_person_detect.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Mon Sep 24 09:17:37 2018
4 |
5 | @author: ren_dong
6 | """
7 |
8 | '''
9 | HOG检测人
10 | '''
11 | import cv2
12 | import numpy as np
13 |
14 |
15 | def is_inside(o, i):
16 | '''
17 | 判断矩形o是不是在i矩形中
18 |
19 | args:
20 | o:矩形o (x,y,w,h)
21 | i:矩形i (x,y,w,h)
22 | '''
23 | ox, oy, ow, oh = o
24 | ix, iy, iw, ih = i
25 | return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih
26 |
27 |
28 | def draw_person(img, person):
29 | '''
30 | 在img图像上绘制矩形框person
31 |
32 | args:
33 | img:图像img
34 | person:人所在的边框位置 (x,y,w,h)
35 | '''
36 | x, y, w, h = person
37 | cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
38 |
39 |
40 | def detect_test():
41 | '''
42 | 检测人
43 | '''
44 | img = cv2.imread('./images/person.jpg')
45 | rows, cols = img.shape[:2]
46 | sacle = 0.5
47 | print('img',img.shape)
48 | img = cv2.resize(img, dsize=(int(cols * sacle), int(rows * sacle)))
49 | # print('img',img.shape)
50 | # img = cv2.resize(img, (128,64))
51 |
52 | # 创建HOG描述符对象
53 | # 计算一个检测窗口特征向量维度:(64/8 - 1)*(128/8 - 1)*4*9 = 3780
54 | '''
55 | winSize = (64,128)
56 | blockSize = (16,16)
57 | blockStride = (8,8)
58 | cellSize = (8,8)
59 | nbins = 9
60 | hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins)
61 | '''
62 | hog = cv2.HOGDescriptor()
63 | # hist = hog.compute(img[0:128,0:64]) 计算一个检测窗口的维度
64 | # print(hist.shape)
65 | detector = cv2.HOGDescriptor_getDefaultPeopleDetector()
66 | print('detector', type(detector), detector.shape)
67 | hog.setSVMDetector(detector)
68 |
69 | # 多尺度检测,found是一个数组,每一个元素都是对应一个矩形,即检测到的目标框
70 | found, w = hog.detectMultiScale(img)
71 | print('found', type(found), found.shape)
72 |
73 | # 过滤一些矩形,如果矩形o在矩形i中,则过滤掉o
74 | found_filtered = []
75 | for ri, r in enumerate(found):
76 | for qi, q in enumerate(found):
77 | # r在q内?
78 | if ri != qi and is_inside(r, q):
79 | break
80 | else:
81 | found_filtered.append(r)
82 |
83 | for person in found_filtered:
84 | draw_person(img, person)
85 |
86 | cv2.imshow('img', img)
87 | cv2.waitKey()
88 | cv2.destroyAllWindows()
89 |
90 |
91 | if __name__ == '__main__':
92 | detect_test()
--------------------------------------------------------------------------------
/5_object_detection/code/5.2_HOG.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Mon Sep 24 18:23:04 2018
4 |
5 | @author: zy
6 | """
7 |
8 | # 代码来源GitHub:https://github.com/PENGZhaoqing/Hog-feature
9 | # https://blog.csdn.net/ppp8300885/article/details/71078555
10 | # https://www.leiphone.com/news/201708/ZKsGd2JRKr766wEd.html
11 |
12 | import cv2
13 | import numpy as np
14 | import math
15 | import matplotlib.pyplot as plt
16 |
17 |
18 | class Hog_descriptor():
19 | '''
20 | HOG描述符的实现
21 | '''
22 |
23 | def __init__(self, img, cell_size=8, bin_size=9):
24 | '''
25 | 构造函数
26 | 默认参数,一个block由2x2个cell组成,步长为1个cell大小
27 | args:
28 | img:输入图像(更准确的说是检测窗口),这里要求为灰度图像 对于行人检测图像大小一般为128x64 即是输入图像上的一小块裁切区域
29 | cell_size:细胞单元的大小 如8,表示8x8个像素
30 | bin_size:直方图的bin个数
31 | '''
32 | self.img = img
33 | '''
34 | 采用Gamma校正法对输入图像进行颜色空间的标准化(归一化),目的是调节图像的对比度,降低图像局部
35 | 的阴影和光照变化所造成的影响,同时可以抑制噪音。采用的gamma值为0.5。 f(I)=I^γ
36 | '''
37 | self.img = np.sqrt(img * 1.0 / float(np.max(img)))
38 | self.img = self.img * 255
39 | # print('img',self.img.dtype) #float64
40 | # 参数初始化
41 | self.cell_size = cell_size
42 | self.bin_size = bin_size
43 | self.angle_unit = 180 / self.bin_size # 这里采用180°
44 | assert type(self.bin_size) == int, "bin_size should be integer,"
45 | assert type(self.cell_size) == int, "cell_size should be integer,"
46 | assert 180 % self.bin_size == 0, "bin_size should be divisible by 180"
47 |
48 | def extract(self):
49 | '''
50 | 计算图像的HOG描述符,以及HOG-image特征图
51 | '''
52 | height, width = self.img.shape
53 | '''
54 | 1、计算图像每一个像素点的梯度幅值和角度
55 | '''
56 | gradient_magnitude, gradient_angle = self.global_gradient()
57 | gradient_magnitude = abs(gradient_magnitude)
58 | '''
59 | 2、计算输入图像的每个cell单元的梯度直方图,形成每个cell的descriptor 比如输入图像为128x64 可以得到16x8个cell,每个cell由9个bin组成
60 | '''
61 | cell_gradient_vector = np.zeros((int(height / self.cell_size), int(width / self.cell_size), self.bin_size))
62 | # 遍历每一行、每一列
63 | for i in range(cell_gradient_vector.shape[0]):
64 | for j in range(cell_gradient_vector.shape[1]):
65 | # 计算第[i][j]个cell的特征向量
66 | cell_magnitude = gradient_magnitude[i * self.cell_size:(i + 1) * self.cell_size,
67 | j * self.cell_size:(j + 1) * self.cell_size]
68 | cell_angle = gradient_angle[i * self.cell_size:(i + 1) * self.cell_size,
69 | j * self.cell_size:(j + 1) * self.cell_size]
70 | cell_gradient_vector[i][j] = self.cell_gradient(cell_magnitude, cell_angle)
71 |
72 | # 将得到的每个cell的梯度方向直方图绘出,得到特征图
73 | hog_image = self.render_gradient(np.zeros([height, width]), cell_gradient_vector)
74 |
75 | '''
76 | 3、将2x2个cell组成一个block,一个block内所有cell的特征串联起来得到该block的HOG特征descriptor
77 | 将图像image内所有block的HOG特征descriptor串联起来得到该image(检测目标)的HOG特征descriptor,
78 | 这就是最终分类的特征向量
79 | '''
80 | hog_vector = []
81 | # 默认步长为一个cell大小,一个block由2x2个cell组成,遍历每一个block
82 | for i in range(cell_gradient_vector.shape[0] - 1):
83 | for j in range(cell_gradient_vector.shape[1] - 1):
84 | # 提取第[i][j]个block的特征向量
85 | block_vector = []
86 | block_vector.extend(cell_gradient_vector[i][j])
87 | block_vector.extend(cell_gradient_vector[i][j + 1])
88 | block_vector.extend(cell_gradient_vector[i + 1][j])
89 | block_vector.extend(cell_gradient_vector[i + 1][j + 1])
90 | '''块内归一化梯度直方图,去除光照、阴影等变化,增加鲁棒性'''
91 | # 计算l2范数
92 | mag = lambda vector: math.sqrt(sum(i ** 2 for i in vector))
93 | magnitude = mag(block_vector) + 1e-5
94 | # 归一化
95 | if magnitude != 0:
96 | normalize = lambda block_vector, magnitude: [element / magnitude for element in block_vector]
97 | block_vector = normalize(block_vector, magnitude)
98 | hog_vector.append(block_vector)
99 | return np.asarray(hog_vector), hog_image
100 |
101 | def global_gradient(self):
102 | '''
103 | 分别计算图像沿x轴和y轴的梯度
104 | '''
105 | gradient_values_x = cv2.Sobel(self.img, cv2.CV_64F, 1, 0, ksize=5)
106 | gradient_values_y = cv2.Sobel(self.img, cv2.CV_64F, 0, 1, ksize=5)
107 | # 计算梯度幅值 这个计算的是0.5*gradient_values_x + 0.5*gradient_values_y
108 | # gradient_magnitude = cv2.addWeighted(gradient_values_x, 0.5, gradient_values_y, 0.5, 0)
109 | # 计算梯度方向
110 | # gradient_angle = cv2.phase(gradient_values_x, gradient_values_y, angleInDegrees=True)
111 | gradient_magnitude, gradient_angle = cv2.cartToPolar(gradient_values_x, gradient_values_y, angleInDegrees=True)
112 | # 角度大于180°的,减去180度
113 | gradient_angle[gradient_angle > 180.0] -= 180
114 | # print('gradient',gradient_magnitude.shape,gradient_angle.shape,np.min(gradient_angle),np.max(gradient_angle))
115 | return gradient_magnitude, gradient_angle
116 |
117 | def cell_gradient(self, cell_magnitude, cell_angle):
118 | '''
119 | 为每个细胞单元构建梯度方向直方图
120 |
121 | args:
122 | cell_magnitude:cell中每个像素点的梯度幅值
123 | cell_angle:cell中每个像素点的梯度方向
124 | return:
125 | 返回该cell对应的梯度直方图,长度为bin_size
126 | '''
127 | orientation_centers = [0] * self.bin_size
128 | # 遍历cell中的每一个像素点
129 | for i in range(cell_magnitude.shape[0]):
130 | for j in range(cell_magnitude.shape[1]):
131 | # 梯度幅值
132 | gradient_strength = cell_magnitude[i][j]
133 | # 梯度方向
134 | gradient_angle = cell_angle[i][j]
135 | # 双线性插值
136 | min_angle, max_angle, weight = self.get_closest_bins(gradient_angle)
137 | orientation_centers[min_angle] += (gradient_strength * (1 - weight))
138 | orientation_centers[max_angle] += (gradient_strength * weight)
139 | return orientation_centers
140 |
141 | def get_closest_bins(self, gradient_angle):
142 | '''
143 | 计算梯度方向gradient_angle位于哪一个bin中,这里采用的计算方式为双线性插值
144 | 具体参考:https://www.leiphone.com/news/201708/ZKsGd2JRKr766wEd.html
145 | 例如:当我们把180°划分为9个bin的时候,分别对应对应0,20,40,...160这些角度。
146 | 角度是10,副值是4,因为角度10介于0-20度的中间(正好一半),所以把幅值
147 | 一分为二地放到0和20两个bin里面去。
148 | args:
149 | gradient_angle:角度
150 | return:
151 | start,end,weight:起始bin索引,终止bin的索引,end索引对应bin所占权重
152 | '''
153 | idx = int(gradient_angle / self.angle_unit)
154 | mod = gradient_angle % self.angle_unit
155 | return idx % self.bin_size, (idx + 1) % self.bin_size, mod / self.angle_unit
156 |
157 | def render_gradient(self, image, cell_gradient):
158 | '''
159 | 将得到的每个cell的梯度方向直方图绘出,得到特征图
160 | args:
161 | image:画布,和输入图像一样大 [h,w]
162 | cell_gradient:输入图像的每个cell单元的梯度直方图,形状为[h/cell_size,w/cell_size,bin_size]
163 | return:
164 | image:特征图
165 | '''
166 | cell_width = self.cell_size / 2
167 | max_mag = np.array(cell_gradient).max()
168 | # 遍历每一个cell
169 | for x in range(cell_gradient.shape[0]):
170 | for y in range(cell_gradient.shape[1]):
171 | # 获取第[i][j]个cell的梯度直方图
172 | cell_grad = cell_gradient[x][y]
173 | # 归一化
174 | cell_grad /= max_mag
175 | angle = 0
176 | angle_gap = self.angle_unit
177 | # 遍历每一个bin区间
178 | for magnitude in cell_grad:
179 | # 转换为弧度
180 | angle_radian = math.radians(angle)
181 | # 计算起始坐标和终点坐标,长度为幅值(归一化),幅值越大、绘制的线条越长、越亮
182 | x1 = int(x * self.cell_size + cell_width + magnitude * cell_width * math.cos(angle_radian))
183 | y1 = int(y * self.cell_size + cell_width + magnitude * cell_width * math.sin(angle_radian))
184 | x2 = int(x * self.cell_size + cell_width - magnitude * cell_width * math.cos(angle_radian))
185 | y2 = int(y * self.cell_size + cell_width - magnitude * cell_width * math.sin(angle_radian))
186 | cv2.line(image, (y1, x1), (y2, x2), int(255 * math.sqrt(magnitude)))
187 | angle += angle_gap
188 | return image
189 |
190 |
191 | if __name__ == '__main__':
192 | # 加载图像
193 | img = cv2.imread('./image/person.jpg')
194 | width = 64
195 | height = 128
196 | img_copy = img[320:320 + height, 570:570 + width][:, :, ::-1]
197 | gray_copy = cv2.cvtColor(img_copy, cv2.COLOR_BGR2GRAY)
198 |
199 | # 显示原图像
200 | plt.figure(figsize=(6.4, 2.0 * 3.2))
201 | plt.subplot(1, 2, 1)
202 | plt.imshow(img_copy)
203 |
204 | # HOG特征提取
205 | hog = Hog_descriptor(gray_copy, cell_size=8, bin_size=9)
206 | hog_vector, hog_image = hog.extract()
207 | print('hog_vector', hog_vector.shape)
208 | print('hog_image', hog_image.shape)
209 |
210 | # 绘制特征图
211 | plt.subplot(1, 2, 2)
212 | plt.imshow(hog_image, cmap=plt.cm.gray)
213 | plt.show()
--------------------------------------------------------------------------------
/5_object_detection/code/5.3_BOW.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Wed Oct 17 09:38:26 2018
4 |
5 | @author: ren_dong
6 | """
7 |
8 | '''
9 | 词袋模型BOW+SVM 目标识别
10 |
11 | 以狗和猫数据集二分类为例
12 | 如果是狗 返回True
13 | 如果是猫 返回False
14 | '''
15 | import numpy as np
16 | import cv2
17 |
18 |
19 | class BOW(object):
20 |
21 | def __init__(self, ):
22 | # 创建一个SIFT对象 用于关键点提取
23 | self.feature_detector = cv2.xfeatures2d.SIFT_create()
24 | # 创建一个SIFT对象 用于关键点描述符提取
25 | self.descriptor_extractor = cv2.xfeatures2d.SIFT_create()
26 |
27 | def path(self, cls, i):
28 | '''
29 | 用于获取图片的全路径
30 | '''
31 | # train_path/dog/dog.i.jpg
32 | return '%s/%s/%s.%d.jpg' % (self.train_path, cls, cls, i + 1)
33 |
34 | def fit(self, train_path, k):
35 | '''
36 | 开始训练
37 |
38 | args:
39 | train_path:训练集图片路径 我们使用的数据格式为 train_path/dog/dog.i.jpg train_path/cat/cat.i.jpg
40 | k:k-means参数k
41 | '''
42 | self.train_path = train_path
43 |
44 | # FLANN匹配 参数algorithm用来指定匹配所使用的算法,可以选择的有LinearIndex、KTreeIndex、KMeansIndex、CompositeIndex和AutotuneIndex,这里选择的是KTreeIndex(使用kd树实现最近邻搜索)
45 | flann_params = dict(algorithm=1, tree=5)
46 | flann = cv2.FlannBasedMatcher(flann_params, {})
47 |
48 | # 创建BOW训练器,指定k-means参数k 把处理好的特征数据全部合并,利用聚类把特征词分为若干类,此若干类的数目由自己设定,每一类相当于一个视觉词汇
49 | bow_kmeans_trainer = cv2.BOWKMeansTrainer(k)
50 |
51 | pos = 'dog'
52 | neg = 'cat'
53 |
54 | # 指定用于提取词汇字典的样本数
55 | length = 10
56 | # 合并特征数据 每个类从数据集中读取length张图片(length个狗,length个猫),通过聚类创建视觉词汇
57 | for i in range(length):
58 | bow_kmeans_trainer.add(self.sift_descriptor_extractor(self.path(pos, i)))
59 | bow_kmeans_trainer.add(self.sift_descriptor_extractor(self.path(neg, i)))
60 |
61 | # 进行k-means聚类,返回词汇字典 也就是聚类中心
62 | voc = bow_kmeans_trainer.cluster()
63 |
64 | # 输出词汇字典 (40, 128)
65 | print(type(voc), voc.shape)
66 |
67 | # 初始化bow提取器(设置词汇字典),用于提取每一张图像的BOW特征描述
68 | self.bow_img_descriptor_extractor = cv2.BOWImgDescriptorExtractor(self.descriptor_extractor, flann)
69 | self.bow_img_descriptor_extractor.setVocabulary(voc)
70 |
71 | # 创建两个数组,分别对应训练数据和标签,并用BOWImgDescriptorExtractor产生的描述符填充
72 | # 按照下面的方法生成相应的正负样本图片的标签 1:正匹配 -1:负匹配
73 | traindata, trainlabels = [], []
74 | for i in range(400): # 这里取200张图像做训练
75 | traindata.extend(self.bow_descriptor_extractor(self.path(pos, i)))
76 | trainlabels.append(1)
77 | traindata.extend(self.bow_descriptor_extractor(self.path(neg, i)))
78 | trainlabels.append(-1)
79 |
80 | # 创建一个SVM对象
81 | self.svm = cv2.ml.SVM_create()
82 | # 使用训练数据和标签进行训练
83 | self.svm.train(np.array(traindata), cv2.ml.ROW_SAMPLE, np.array(trainlabels))
84 |
85 | def predict(self, img_path):
86 | '''
87 | 进行预测样本
88 | '''
89 | # 提取图片的BOW特征描述
90 | data = self.bow_descriptor_extractor(img_path)
91 | res = self.svm.predict(data)
92 | print(img_path, '\t', res[1][0][0])
93 |
94 | # 如果是狗 返回True
95 | if res[1][0][0] == 1.0:
96 | return True
97 | # 如果是猫,返回False
98 | else:
99 | return False
100 |
101 | def sift_descriptor_extractor(self, img_path):
102 | '''
103 | 特征提取:提取数据集中每幅图像的特征点,然后提取特征描述符,形成特征数据(如:SIFT或者SURF方法);
104 | '''
105 | im = cv2.imread(img_path, 0)
106 | return self.descriptor_extractor.compute(im, self.feature_detector.detect(im))[1]
107 |
108 | def bow_descriptor_extractor(self, img_path):
109 | '''
110 | 提取图像的BOW特征描述(即利用视觉词袋量化图像特征)
111 | '''
112 | im = cv2.imread(img_path, 0)
113 | return self.bow_img_descriptor_extractor.compute(im, self.feature_detector.detect(im))
114 |
115 |
116 | if __name__ == '__main__':
117 | # 测试样本数量,测试结果
118 | test_samples = 100
119 | test_results = np.zeros(test_samples, dtype=np.bool)
120 |
121 | # 训练集图片路径 狗和猫两类 进行训练
122 | train_path = './data/cat_and_dog/data/train'
123 | bow = BOW()
124 | bow.fit(train_path, 40)
125 |
126 | # 指定测试图像路径
127 | for index in range(test_samples):
128 | dog = './data/cat_and_dog/data/train/dog/dog.{0}.jpg'.format(index)
129 | dog_img = cv2.imread(dog)
130 |
131 | # 预测
132 | dog_predict = bow.predict(dog)
133 | test_results[index] = dog_predict
134 |
135 | # 计算准确率
136 | accuracy = np.mean(test_results.astype(dtype=np.float32))
137 | print('测试准确率为:', accuracy)
138 |
139 | # 可视化最后一个
140 | font = cv2.FONT_HERSHEY_SIMPLEX
141 | if test_results[0]:
142 | cv2.putText(dog_img, 'Dog Detected', (10, 30), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
143 |
144 | cv2.imshow('dog_img', dog_img)
145 |
146 | cv2.waitKey(0)
147 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/5_object_detection/code/readme:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/5_object_detection/images/person.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/5_object_detection/images/person.jpg
--------------------------------------------------------------------------------
/5_object_detection/images/readme:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/5_object_detection/readme:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/6_object_traack/code/5.4_track.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 |
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | 帧差法实现目标追踪
8 | @author 2019-1-22 19:56
9 |
10 | '''
11 | camera = cv2.VideoCapture(0)
12 |
13 | es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,4))
14 | kernel = np.ones((5,5), np.uint8)
15 | background = None
16 |
17 | while(True):
18 | ret, frame = camera.read()
19 | if background is None:
20 | background = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
21 | background = cv2.GaussianBlur(background, (21,21), 0)
22 | continue
23 |
24 |
25 | gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
26 | gray_frame = cv2.GaussianBlur(gray_frame, (21, 21), 0)
27 |
28 | diff = cv2.absdiff(background, gray_frame)
29 | diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
30 | diff = cv2.dilate(diff, es, iterations=2)
31 |
32 | image, cnts, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
33 |
34 | for c in cnts:
35 | if cv2.contourArea(c) < 1500:
36 | continue
37 | (x, y, w, h) = cv2.boundingRect(c)
38 | cv2.rectangle(frame, (x,y), (x+w,y+h), (0, 255, 0), 2)
39 |
40 | cv2.imshow("contours", frame)
41 | cv2.imshow("diff", diff)
42 | if cv2.waitKey(50) & 0xff == ord("q"):
43 | break
44 |
45 | cv2.destroyAllWindows()
46 | camera.release()
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/6_object_traack/code/6.1_track.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 |
3 | import cv2
4 | import numpy as np
5 |
6 | '''
7 | 帧差法实现目标追踪
8 | @author 2019-1-22 19:56
9 |
10 | 第一帧设为背景--> frame灰度化+高斯模糊 -->计算差异-->寻找轮廓 设定阈值 -->绘框并显示
11 |
12 | '''
13 | camera = cv2.VideoCapture(0)
14 |
15 | es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,4))
16 | kernel = np.ones((5,5), np.uint8)
17 | background = None
18 |
19 | while(True):
20 | ret, frame = camera.read()
21 | if background is None:
22 | background = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
23 | background = cv2.GaussianBlur(background, (21,21), 0)
24 | continue
25 |
26 |
27 | gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
28 | gray_frame = cv2.GaussianBlur(gray_frame, (21, 21), 0)
29 |
30 | diff = cv2.absdiff(background, gray_frame)
31 | diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
32 | diff = cv2.dilate(diff, es, iterations=2)
33 |
34 | image, cnts, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
35 |
36 | for c in cnts:
37 | if cv2.contourArea(c) < 1500:
38 | continue
39 | (x, y, w, h) = cv2.boundingRect(c)
40 | cv2.rectangle(frame, (x,y), (x+w,y+h), (0, 255, 0), 2)
41 |
42 | cv2.imshow("contours", frame)
43 | cv2.imshow("diff", diff)
44 | if cv2.waitKey(50) & 0xff == ord("q"):
45 | break
46 |
47 | cv2.destroyAllWindows()
48 | camera.release()
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/6_object_traack/code/6.2_KNN.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 |
3 | import cv2
4 | import numpy as np
5 | '''
6 | 背景分割器KNN实现运动检测
7 | @author 2018-1-23 18:53
8 |
9 | KNN -->阈值化去除阴影-->膨胀去粗白色斑点-->寻找轮廓-->绘框并显示
10 | '''
11 | bs = cv2.createBackgroundSubtractorKNN(detectShadows = True)
12 | camera = cv2.VideoCapture('1.mp4')
13 |
14 | while True:
15 | ret, frame = camera.read()
16 | fgmask = bs.apply(frame)
17 | th = cv2.threshold(fgmask.copy(), 244, 255, cv2.THRESH_BINARY)[1]
18 | dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)), iterations = 2)
19 |
20 | image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
21 |
22 | for c in contours:
23 | if cv2.contourArea(c) > 1600:
24 | (x, y, w, h) = cv2.boundingRect(c)
25 | cv2.rectangle(frame, (x, y), (x+w, y+h), (255,255,0), 2)
26 |
27 | cv2.imshow("mog", fgmask)
28 | cv2.imshow("thresh", th)
29 | cv2.imshow("detection", frame)
30 |
31 | if cv2.waitKey(30) & 0xff == 27:
32 | break
33 | camera.release()
34 | cv2.destroyAllWindows()
--------------------------------------------------------------------------------
/6_object_traack/code/6.3_meanshift.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | import numpy as np
3 | import cv2
4 | '''
5 | @author 2019-1-25 20:25
6 | Meanshift 均值漂移
7 |
8 | 标记感兴趣区域-->HSV空间 -->计算直方图+归一化 --> 反向投影 --> meanshift -->绘框并显示
9 |
10 | '''
11 |
12 | #标记初始感兴趣的区域
13 | cap = cv2.VideoCapture(0)
14 | ret, frame = cap.read()
15 | r,h,c,w = 10, 200, 10, 20
16 | track_window = (c,r,w,h)
17 |
18 | roi = frame[r:r+h, c:c+w]
19 | #BGR ---> HSV
20 | hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
21 |
22 | #构建mask,给定array上下界
23 | mask = cv2.inRange(hsv_roi, np.array((100., 30, 32.)),np.array((180, 120, 255)))
24 |
25 | #计算直方图
26 | roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0,180])
27 |
28 | #线性直方图归一化
29 | cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
30 |
31 | #设定meanshift迭代停止条件
32 | term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
33 |
34 | while True:
35 | ret, frame = cap.read()
36 |
37 | if ret == True:
38 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
39 | dst = cv2.calcBackProject([hsv], [0], roi_hist, [0,180], 1)
40 |
41 | #对ROI进行meanshift 给定window和停止条件
42 | ret, track_window = cv2.meanShift(dst, track_window, term_crit)
43 |
44 | #重新计算window 然后在原图绘制矩形框
45 | x,y,w,h = track_window
46 | img2 = cv2.rectangle(frame, (x,y), (x+w,y+h), 255, 2)
47 | cv2.imshow('img2', img2)
48 |
49 | k = cv2.waitKey(60) &0xff
50 | if k == 27:
51 | break
52 | else:
53 | break
54 |
55 | cv2.destroyAllWindows()
56 | cap.release()
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/6_object_traack/code/6.4_camshift.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import numpy as np
3 | import cv2
4 |
5 | '''
6 | @author 2019-1-25 21:07
7 | camshift
8 |
9 | 标记感兴趣区域-->HSV空间 -->计算直方图+归一化 --> 反向投影 --> camshift -->绘框并显示
10 |
11 | '''
12 |
13 | # 标记初始感兴趣的区域
14 | cap = cv2.VideoCapture(0)
15 | ret, frame = cap.read()
16 | r, h, c, w = 10, 200, 10, 20
17 | track_window = (c, r, w, h)
18 |
19 | roi = frame[r:r + h, c:c + w]
20 | # BGR ---> HSV
21 | hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
22 |
23 | # 构建mask,给定array上下界
24 | mask = cv2.inRange(hsv_roi, np.array((100., 30, 32.)), np.array((180, 120, 255)))
25 |
26 | # 计算直方图
27 | roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
28 |
29 | # 线性直方图归一化
30 | cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
31 |
32 | # 设定meanshift迭代停止条件
33 | term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
34 |
35 | while True:
36 | ret, frame = cap.read()
37 |
38 | if ret == True:
39 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
40 | dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
41 |
42 | # 对ROI进行meanshift 给定window和停止条件
43 | ret, track_window = cv2.CamShift(dst, track_window, term_crit)
44 | #返回旋转矩形的四个顶点points
45 | pts = cv2.boxPoints(ret)
46 | pts = np.int0(pts)
47 | #绘制多边形曲线图
48 | img2 = cv2.polylines(frame, [pts], True, 255, 2)
49 |
50 | cv2.imshow('img2', img2)
51 |
52 | k = cv2.waitKey(60) & 0xff
53 | if k == 27:
54 | break
55 | else:
56 | break
57 |
58 | cv2.destroyAllWindows()
59 | cap.release()
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/6_object_traack/code/readme:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenCV_Notes
2 | 作为自己学习OpenCv的记录笔记
3 |
4 | 邮箱地址:17854257054@163.com
5 |
6 |
7 | ## Welcome star!!!!!!
8 |
9 | ### 一 图像预处理
10 |
11 | 图片读取 显示 保存 读取
12 |
13 | #### 模糊滤波
14 | 


15 |
16 | #### 轮廓检测 #### 多边形 直线检测
17 |
18 | 
19 |
20 | #### 圆检测
21 |
22 |
23 |
24 | ## 二 图像分割
25 |
26 | #### Grabcut算法
27 | 
28 |
29 | #### 分水岭算法
30 |
31 | 


32 |
33 | ## 三 人脸检测
34 |
35 | 
36 |
--------------------------------------------------------------------------------
/face_recognition/facial.py:
--------------------------------------------------------------------------------
1 | from PIL import Image, ImageDraw
2 | import face_recognition
3 |
4 | # Load the jpg file into a numpy array
5 | image = face_recognition.load_image_file("images/002.jpg")
6 |
7 | # Find all facial features in all the faces in the image
8 | face_landmarks_list = face_recognition.face_landmarks(image)
9 |
10 | print("I found {} face(s) in this photograph.".format(len(face_landmarks_list)))
11 |
12 | # Create a PIL imagedraw object so we can draw on the picture
13 | pil_image = Image.fromarray(image)
14 | d = ImageDraw.Draw(pil_image)
15 |
16 | for face_landmarks in face_landmarks_list:
17 | print face_landmarks.keys()
18 | # Print the location of each facial feature in this image
19 | for facial_feature in face_landmarks.keys():
20 | print("The {} in this face has the following points: {}".format(facial_feature, face_landmarks[facial_feature]))
21 |
22 | # Let's trace out each facial feature in the image with a line!
23 | for facial_feature in face_landmarks.keys():
24 | d.line(face_landmarks[facial_feature], fill=(255,0,255), width=2)
25 |
26 | # Show the picture
27 | pil_image.show()
28 | pil_image.save('images/11.jpg')
--------------------------------------------------------------------------------
/face_recognition/find_face.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 | import face_recognition
3 |
4 | # Load the jpg file into a numpy array
5 | image = face_recognition.load_image_file("images/003.jpg")
6 |
7 | # Find all the faces in the image using the default HOG-based model.
8 | # This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.
9 |
10 | face_locations = face_recognition.face_locations(image)
11 | # face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn")
12 | print("I found {} face(s) in this photograph.".format(len(face_locations)))
13 |
14 | for face_location in face_locations:
15 |
16 | # Print the location of each face in this image
17 | top, right, bottom, left = face_location
18 | print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))
19 |
20 | # You can access the actual face itself like this:
21 | face_image = image[top:bottom, left:right]
22 | pil_image = Image.fromarray(face_image)
23 | pil_image.show()
--------------------------------------------------------------------------------
/face_recognition/find_face_cnn.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 | import face_recognition
3 |
4 | # Load the jpg file into a numpy array
5 | image = face_recognition.load_image_file("images/004.jpg")
6 |
7 | # Find all the faces in the image using a pre-trained convolutional neural network.
8 | # This method is more accurate than the default HOG model, but it's slower
9 | # unless you have an nvidia GPU and dlib compiled with CUDA extensions. But if you do,
10 | # this will use GPU acceleration and perform well.
11 |
12 | face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn")
13 |
14 | print("I found {} face(s) in this photograph.".format(len(face_locations)))
15 |
16 | for face_location in face_locations:
17 |
18 | # Print the location of each face in this image
19 | top, right, bottom, left = face_location
20 | print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))
21 |
22 | # You can access the actual face itself like this:
23 | face_image = image[top:bottom, left:right]
24 | pil_image = Image.fromarray(face_image)
25 | pil_image.show()
--------------------------------------------------------------------------------
/face_recognition/images/001.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/001.jpg
--------------------------------------------------------------------------------
/face_recognition/images/002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/002.jpg
--------------------------------------------------------------------------------
/face_recognition/images/003.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/003.jpg
--------------------------------------------------------------------------------
/face_recognition/images/004.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/004.jpg
--------------------------------------------------------------------------------
/face_recognition/images/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/11.jpg
--------------------------------------------------------------------------------
/face_recognition/images/22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/22.jpg
--------------------------------------------------------------------------------
/face_recognition/images/33.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rendong3/OpenCV-Notes/937d8107d6e2418299fed062a1be07ac0e36bd0e/face_recognition/images/33.jpg
--------------------------------------------------------------------------------
/face_recognition/images/readme:
--------------------------------------------------------------------------------
1 | 这里和往常一样, 存储以上程序用到的图片
2 |
--------------------------------------------------------------------------------
/face_recognition/makeups.py:
--------------------------------------------------------------------------------
1 | from PIL import Image, ImageDraw
2 | import face_recognition
3 |
4 | # Load the jpg file into a numpy array
5 | image = face_recognition.load_image_file("images/004.jpg")
6 |
7 | # Find all facial features in all the faces in the image
8 | face_landmarks_list = face_recognition.face_landmarks(image)
9 |
10 | for face_landmarks in face_landmarks_list:
11 | pil_image = Image.fromarray(image)
12 | d = ImageDraw.Draw(pil_image, 'RGBA')
13 |
14 | # Make the eyebrows into a nightmare
15 | d.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128))
16 | d.polygon(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 128))
17 | d.line(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 150), width=5)
18 | d.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=5)
19 |
20 | # Gloss the lips
21 | d.polygon(face_landmarks['top_lip'], fill=(150, 0, 0, 128))
22 | d.polygon(face_landmarks['bottom_lip'], fill=(150, 0, 0, 128))
23 | d.line(face_landmarks['top_lip'], fill=(150, 0, 0, 64), width=8)
24 | d.line(face_landmarks['bottom_lip'], fill=(150, 0, 0, 64), width=8)
25 |
26 | # Sparkle the eyes
27 | d.polygon(face_landmarks['left_eye'], fill=(255, 255, 255, 30))
28 | d.polygon(face_landmarks['right_eye'], fill=(255, 255, 255, 30))
29 |
30 | # Apply some eyeliner
31 | d.line(face_landmarks['left_eye'] + [face_landmarks['left_eye'][0]], fill=(0, 0, 0, 110), width=6)
32 | d.line(face_landmarks['right_eye'] + [face_landmarks['right_eye'][0]], fill=(0, 0, 0, 110), width=6)
33 |
34 | pil_image.show()
--------------------------------------------------------------------------------
/face_recognition/profile.py:
--------------------------------------------------------------------------------
1 | #coding=utf-8
2 | #绘制面部轮廓
3 | import cv2
4 | import face_recognition
5 | from PIL import Image, ImageDraw
6 |
7 | # 将图片文件加载到numpy 数组中
8 | img = cv2.imread('images/001.jpg')
9 | img1 = cv2.resize(img, (400,600), interpolation=cv2.INTER_CUBIC)
10 | cv2.imwrite('images/002.jpg',img1)
11 | image = face_recognition.load_image_file('images/002.jpg')
12 |
13 | #查找图像中所有面部的所有面部特征
14 | face_landmarks_list = face_recognition.face_landmarks(image)
15 | print("I found {} face(s) in this photograph.".format(len(face_landmarks_list)))
16 |
17 | for face_landmarks in face_landmarks_list:
18 | facial_features = [
19 | 'chin', 'left_eyebrow', 'right_eyebrow', 'nose_bridge', 'nose_tip',
20 | 'left_eye', 'right_eye', 'top_lip', 'bottom_lip'
21 | ]
22 | pil_image = Image.fromarray(image)
23 |
24 | d = ImageDraw.Draw(pil_image)
25 |
26 | for facial_feature in facial_features:
27 | d.line(face_landmarks[facial_feature], fill=(0, 255, 0), width=2)
28 | print("The {} in this face has the following points: {}".format(facial_feature, face_landmarks[facial_feature]))
29 |
30 | pil_image.show()
31 |
32 |
--------------------------------------------------------------------------------
/face_recognition/readme:
--------------------------------------------------------------------------------
1 | 记录对于face_recongnition人脸识别库的简单应用
2 |
3 | 包括绘制脸部轮廓, 提取图片人脸,
4 |
5 | 人脸美妆
6 |
7 | 
8 |
--------------------------------------------------------------------------------
/video2img/Readme:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/video2img/avi2img.py:
--------------------------------------------------------------------------------
1 | #-*- coding: utf-8 -*-
2 | import os
3 | import cv2
4 |
5 |
6 | video_path = '/home/ren_dong/PycharmProjects/OpenCv/blog/video/1.avi'
7 | save_path = '/home/ren_dong/PycharmProjects/OpenCv/blog/img/'
8 |
9 | try:
10 | if not os.path.exists(save_path):
11 | os.mkdir(save_path)
12 | except:
13 | print('path is exist')
14 |
15 |
16 | def video2img(video_path, save_path):
17 |
18 | cap = cv2.VideoCapture(video_path)
19 | isopened = cap.isOpened()
20 |
21 | i = 1
22 | if cap.isOpened():
23 | flag, frame = cap.read()
24 |
25 | else:
26 | flag = False
27 | print('video is not open..')
28 |
29 |
30 | while(flag):
31 |
32 | flag, frame = cap.read()
33 | cv2.imwrite(save_path + str(i) + '.jpg', frame)
34 | i += 1
35 |
36 |
37 | cap.release()
38 | if __name__ == '__main__':
39 |
40 | video2img(video_path, save_path)
41 |
--------------------------------------------------------------------------------
/video2img/img2avi.py:
--------------------------------------------------------------------------------
1 | import os
2 | import cv2
3 |
4 |
5 | def img2avi():
6 |
7 | file_path = '/home/ren_dong/PycharmProjects/OpenCv/blog/imgs'
8 | save_path = file_path + '/' + '%s.avi' % str('result')
9 |
10 | file_list = os.listdir(file_path)
11 | #视频的帧速率,秒为单位,一秒播放多少张图片
12 | fps = 2
13 | img = cv2.imread('/home/ren_dong/PycharmProjects/OpenCv/blog/imgs/000001.jpg')
14 | size = (img.shape[1],img.shape[0])
15 | #size视频图片的尺寸
16 | fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
17 | videoWriter = cv2.VideoWriter(save_path, fourcc, float(fps), size)
18 | #cv2.VideoWriter(1,2,3,4)
19 | #参数1 文件名称 参数2:选择编译器 参数3:设置帧率 参数4:设置视频尺寸
20 |
21 |
22 | for item in file_list:
23 | if item.endswith('.jpg'):
24 | item = file_path + '/' + item
25 | img = cv2.imread(item)
26 | img = cv2.resize(img, size)
27 | videoWriter.write(img)
28 |
29 |
30 | videoWriter.release()
31 | cv2.destroyAllWindows()
32 |
33 |
34 | if __name__ == '__main__':
35 | img2avi()
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------