cv(四)

1.直方图

 1 '''利用直方图调整图像的对比度叫做直方图均衡化(直方图均衡化都是基于灰度图像)
 2         1.局部直方图均衡化
 3         2.全局直方图均衡化
 4     直方图比较图像相似度是比较粗略的比较
 5 '''
 6 
 7 import cv2 as cv
 8 import matplotlib.pyplot as plt
 9 import numpy as np
10 
11 
12 def plot_demo(image):
13     plt.hist(image.ravel(), 256, [0, 256])  # image.ravel()将图像展开,256为bins数量,[0, 256]为范围
14     plt.show()
15 
16 
17 def image_hist(image):
18     color = ('blue', 'green', 'red')
19     for i, color in enumerate(color):
20 
21         # 计算出直方图,calcHist(images, channels, mask, histSize(有多少个bin), ranges[, hist[, accumulate]]) -> hist
22         # hist 是一个 256x1 的数组,每一个值代表了与该灰度值对应的像素点数目。
23 
24         hist = cv.calcHist(image, [i], None, [256], [0, 256])
25         print(hist.shape)
26         plt.plot(hist, color=color)
27         plt.xlim([0, 256])
28     plt.show()
29 
30 
31 def equalHist_demo(image):
32     gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
33 
34     # 全局直方图均衡化,用于增强图像对比度,即黑的更黑,白的更白
35     dst = cv.equalizeHist(gray)
36     cv.imshow("equalHist_demo", dst)
37 
38     # 局部直方图均衡化
39     clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
40     clahe_dst = clahe.apply(gray)
41     cv.imshow("clahe", clahe_dst)
42 
43 
44 # 创建直方图
45 def create_rgb_demo(image):
46     h, w, c = image.shape
47     rgbHist = np.zeros([16*16*16, 1], np.float32)  # 直方图初始化
48     bsize = 256 / 16
49     for row in range(h):
50         for col in range(w):
51             b = image[row, col, 0]
52             g = image[row, col, 1]
53             r = image[row, col, 2]
54             index = np.int(b/bsize)*16*16 + np.int(g/bsize)*16 + np.int(r/bsize)
55             rgbHist[np.int(index), 0] = rgbHist[np.int(index), 0] + 1
56 
57     return rgbHist
58 
59 
60 # 利用直方图比较相似性,用巴氏和相关性比较
61 def hist_compare(image1, image2):
62     hist1 = create_rgb_demo(image1)
63     hist2 = create_rgb_demo(image2)
64     match1 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_BHATTACHARYYA)  # 巴氏距离越小越相似
65     match2 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_CORREL)  # 相关性越大越相似
66     match3 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_CHISQR)  # 卡方越小越相似
67     print("巴式距离:%s, 相关性:%s, 卡方:%s"%(match1, match2, match3))
68 
69 if __name__ == '__main__':
70     src = cv.imread("../images/rice.png")  # 读入图片放进src中
71     cv.namedWindow("demo")  # 创建窗口
72     cv.imshow("demo", src)  # 将src图片放入该创建的窗口中
73     # plot_demo(src)
74     image_hist(src)
75 
76     # equalHist_demo(src)
77     image1 = cv.imread("../images/rice.png")
78     image2 = cv.imread("../images/noise_rice.png")
79 
80     # create_rgb_demo(image1)
81     # cv.imshow("image1", image1)
82     # cv.imshow("image2", image2)
83     # hist_compare(image1=image1, image2=image2) # 如果输入的两个图像大小不一样也可以比较,不过最好做个归一化
84 
85     cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
86     cv.destroyAllWindows()  # 关闭所有窗口
直方图均衡化

2.直方图反向投影

 1 import cv2 as cv
 2 import numpy as np
 3 import matplotlib.pyplot as plt
 4 
 5 
 6 def hist2d_demo(image):  # 建立2d直方图
 7     hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
 8     hist = cv.calcHist([image], [0, 1], None, [180, 360], [0, 180, 0, 256])  # 计算直方图
 9     print(hist.shape)
10     # cv.imshow("hist2d_demo", hist)
11     plt.imshow(hist, interpolation="nearest")  # 直方图显示 interpolation="nearest"指定插值方式
12     plt.title("2D Histogram")
13     plt.show()
14 
15 
16 # OpenCV 提供的函数 cv2.calcBackProject() 可以用来做直方图反向 投影。
17 # 它的参数与函数 cv2.calcHist 的参数基本相同。其中的一个参数是我 们要查找目标的直方图。
18 # 同样再使用目标的直方图做反向投影之前我们应该先对其做归一化处理。
19 # 返回的结果是一个概率图像
20 def back_projection_demo():
21     """
22     反向投影可以用来做图像分割,或者在图像中找寻我们感兴趣的部分。
23     它会输出与输入图像(待搜索)同样大小的图像,其中的每一个像素值代表了输入图像上对应点属于目标对象的概率。
24     输出图像中像素值越高(越白)的点就越可能代表我们要搜索的目标 (在输入图像所在的位置)。
25     直方图投影经常与camshift 算法等一起使用。
26     步骤:
27     1. 为一张包含我们要查找目标的图像创建直方图,我们要查找的对象要尽量占满这张图像。
28         最好使用颜色直方图,因为一个物体的颜色要比它的灰 度能更好的被用来进行图像分割与对象识别。
29     2. 们再把这个颜色直方图投 影到输入图像中寻找我们的目标,
30         也就是找到输入图像中的每一个像素点的像素值在直方图中对应的概率,这样我们就得到一个概率图像。
31     3. 设置适当的阈值对概率图像进行二值化
32     """
33     sample = cv.imread("../images/roi.png")
34     target = cv.imread("../images/CrystalLiu3.jpg")
35     roi_hsv = cv.cvtColor(sample, cv.COLOR_BGR2HSV)
36     target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV)
37 
38     cv.imshow("sample", sample)
39     cv.imshow("target", target)
40 
41     roiHist = cv.calcHist([roi_hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
42 
43     # 归一化:原始图像,结果图像,映射到结果图像中的最小值,最大值,归一化类型
44     # cv.NORM_MINMAX对数组的所有值进行转化,使它们线性映射到最小值和最大值之间
45     # 归一化后的图像便于显示,归一化后到0,255之间了
46     cv.normalize(roiHist, roiHist, 0, 255, cv.NORM_MINMAX)
47     dst = cv.calcBackProject([target_hsv], [0, 1], roiHist, [0, 180, 0, 256], 1)
48     cv.imshow("backProjectionDemo", dst)
49 
50 
51 if __name__ == '__main__':
52     src = cv.imread("../images/CrystalLiu1.jpg")  # 读入图片放进src中
53     cv.namedWindow("Crystal Liu")  # 创建窗口
54     cv.imshow("Crystal Liu", src)  # 将src图片放入该创建的窗口中
55     # hist2d_demo(src)
56     back_projection_demo()
57 
58     cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
59     cv.destroyAllWindows()  # 关闭所有窗口
反向投影
 1 import cv2 as cv
 2 import numpy as np
 3 
 4 
 5 """
 6 在很多基础应用中背景检出都是一个非常重要的步骤。
 7 例如顾客统计,使用一个静态摄像头来记录进入和离开房间的人数,或者是交通摄像头,需要提取交通工具的信息等。
 8 在所有的这些例子中,首先要将人或车单独提取出来。技术上来说,我们需要从静止的背景中提取移动的前景。
 9 如果图像中的交通工具还有影子的话,那这个工作就更难了,因为影子也在移动,
10 仅仅使用减法会把影子也当成前景,真是一件很复杂的事情。 
11 为了实现这个目的科学家们已经提出了几种算法。OpenCV 中已经包含了 其中三种比较容易使用的方法
12 """
13 
14 
15 def create_background_sub():
16     """
17     BackgroundSubtractorMOG 这是一个以混合高斯模型为基础的前景/背景分割算法。
18     它使用 K(K=3 或 5)个高斯分布混合对背景像素进行建模。使用这些颜色(在整个视频中)存在时间的长短作为混合的权重。
19     背景的颜色一般持续的时间最长,而且更加静止。一个像素怎么会有分布呢?在 x,y 平面上一个像素就是一个像素没有分布,
20     但是我们现在讲的背景建模是基于时间序列的,因此每一个像素点所在的位置在整个时间序列中就会有很多值,从而构成一个分布。
21     在编写代码时,我们需要使用函数:cv2.createBackgroundSubtractorMOG() 创建一个背景对象。
22     这个函数有些可选参数,比如要进行建模场景的时间长度, 高斯混合成分的数量,阈值等。将他们全部设置为默认值。
23     然后在整个视频中我们是需要使用 backgroundsubtractor.apply() 就可以得到前景的掩模
24     BackgroundSubtractorMOG2,也是以高斯混合模型为基础的背景/前景分割算法。
25     这个算法的一个特点是它为每 一个像素选择一个合适数目的高斯分布。(上一个方法中我们使用是 K 高斯分布)。
26     这样就会对由于亮度等发生变化引起的场景变化产生更好的适应。
27      和前面一样我们需要创建一个背景对象。但在这里我们我们可以选择是否 检测阴影。
28      如果 detectShadows = True(默认值),它就会检测并将影子标记 出来,但是这样做会降低处理速度。影子会被标记为灰色。
29     """
30     cap = cv.VideoCapture('../images/vtest.avi')
31 
32     # 创建一个背景对象
33     # fgbg = cv.createBackgroundSubtractorKNN()
34     fgbg = cv.createBackgroundSubtractorMOG2()
35 
36     while (1):
37         ret, frame = cap.read()
38         fgmask = fgbg.apply(frame)  # 将背景对象应用到当前帧中得到前景的掩模
39         cv.imshow('frame', fgmask)
40         k = cv.waitKey(30) & 0xff
41         if k == 27:
42             break
43 
44     cap.release()
45     cv.destroyAllWindows()
46 
47 
48 def background_subtractorGMG():
49     """
50     此算法结合了静态背景图像估计和每个像素的贝叶斯分割。
51     这是 2012 年 Andrew_B.Godbehere,Akihiro_Matsukawa 和 Ken_Goldberg 在文章 中提出的。
52     它使用前面很少的图像(默认为前 120 帧)进行背景建模。使用了概率前景估计算法(使用贝叶斯估计鉴定前景)。
53     这是一种自适应的估计,新观察到的 对象比旧的对象具有更高的权重,从而对光照变化产生适应。
54     一些形态学操作 如开运算闭运算等被用来除去不需要的噪音。在前几帧图像中你会得到一个黑 色窗口。
55      对结果进行形态学开运算对与去除噪声很有帮助。
56     """
57     cap = cv.VideoCapture('../images/vtest.avi')
58 
59     kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3))
60     fgbg = cv.createBackgroundSubtractorKNN()
61 
62     while (1):
63         ret, frame = cap.read()
64         fgmask = fgbg.apply(frame)  # 将背景对象应用到当前帧中得到前景的掩模
65         fgmask = cv.morphologyEx(fgmask, cv.MORPH_OPEN, kernel)
66 
67         cv.imshow('frame', fgmask)
68         k = cv.waitKey(30) & 0xff
69         if k == 27:
70             break
71 
72 
73 def main():
74     # create_background_sub()
75     background_subtractorGMG()
76     cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
77     cv.destroyAllWindows()  # 关闭所有窗口
78 
79 
80 if __name__ == '__main__':
81     main()
反向投影2
  1 # coding:utf8
  2 import cv2 as cv
  3 import numpy as np
  4 import time
  5 
  6 
  7 def mean_shift_demo():
  8     """
  9     原理:假设我们有一堆点(比如直方 图反向投影得到的点),和一个小的圆形窗口,
 10     我们要完成的任务就是将这个窗 口移动到最大灰度密度处(或者是点最多的地方)。
 11     例如,初始窗口“C1”,圆心“C1_o”,而窗口中所有点质心却是“C1_r”,此时圆心和点的质心没有重合。
 12     所以移动圆心 C1_o 到质心 C1_r,这样我们就得到了一个新的窗口。再找新窗口内所有点的质心,
 13     大多数情况下还是不重合的,所以重复上面的操作:将新窗口的中心移动到新的质心。
 14     就这样不停的迭代操作直到窗口的中心和其所 包含点的质心重合为止(或者有一点小误差)。
 15     按照这样的操作我们的窗口最终会落在像素值(和)最大的地方。
 16     通常情况下我们要使用直方图方向投影得到的图像和目标对象的起始位置。
 17     当目标对象的移动会反映到直方图反向投影图中。
 18     就这样,meanshift 算法就把我们的窗口移动到图像中灰度密度最大的区域了。
 19     要在 OpenCV 中使用 Meanshift 算法首先我们要对目标对象进行设置, 计算目标对象的直方图,
 20     这样在执行 meanshift 算法时我们就可以将目标对象反向投影到每一帧中去了。
 21     另外我们还需要提供窗口的起始位置。在这里我们只计算 H(Hue)通道的直方图,
 22     同样为了避免低亮度造成的影响,我们使用函数 cv2.inRange() 将低亮度的值忽略掉。
 23     """
 24     # cap = cv.VideoCapture('cv.gif')
 25     cap = cv.VideoCapture("../images/slow.mp4")
 26     ret, frame = cap.read()  # 获取第一帧
 27 
 28     # 设置初始窗口位置
 29     # r, h, c, w = 97, 130, 450, 125
 30     r, h, c, w = 210, 80, 300, 125  # r,c 左上角坐标,h,w 高宽
 31     track_window = (c, r, w, h)
 32 
 33     # 设置兴趣区域
 34     roi = frame[r:r+h, c:c+w]
 35 
 36     hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
 37 
 38     # 设置掩模,即剔除部分影响亮度的值
 39     mask = cv.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
 40 
 41     # 计算直方图
 42     roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180])
 43     cv.normalize(roi_hist, roi_hist,0, 255, cv.NORM_MINMAX)  # 归一化
 44 
 45     # 设置迭代条件,10次迭代,或至少移动一次
 46     term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)
 47 
 48     while True:
 49         ret, frame = cap.read()
 50 
 51         if ret is True:
 52             hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
 53             dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
 54 
 55             # 用meanShift算法获得新窗口,从而实现迭代
 56             ret, track_window = cv.meanShift(dst, track_window, term_crit)
 57 
 58             # 在图片中画出该识别出来的窗口
 59             x, y, w, h = track_window
 60             img2 = cv.rectangle(frame, (x, y), (x + w, y + h), 255, 2)
 61             cv.imshow('img2', img2)
 62 
 63             c = cv.waitKey(60) & 0xff
 64             if c == 27:
 65                 break
 66             else:
 67                 print(c)
 68                 print(time.strftime('%H_%M_%S',time.localtime(time.time())))
 69                 # cv.imwrite('../images/'+time.strftime('%H_%M_%S',time.localtime(time.time()))+'.jpg', img2)
 70         else:
 71             break
 72 
 73 
 74 def cam_shift_demo():
 75     """
 76     我们的窗口的大小是固定的,而汽车由远及近(在视觉上)是一个逐渐变大的过程,固定的窗口是不合适的。
 77     所以我们需要根据目标的大小和角度来对窗口的大小和角度进行修订。
 78     OpenCVLabs 为我们带来的解决方案(1988 年):一个被叫做 CAMshift的算法。
 79     这个算法首先要使用 meanshift,meanshift 找到(并覆盖)目标之后, 再去调整窗口的大小。
 80     它还会计算目标对象的最佳外接椭圆的 角度,并以此调节窗口角度。
 81     然后使用更新后的窗口大小和角度来在原来的位 置继续进行 meanshift。
 82     重复这个过程知道达到需要的精度。
 83     OpenCV中Camshift与 Meanshift 基本一样,但是返回的结果是一个带旋转角度的矩形(这是 我们的结果),
 84     以及这个矩形的参数(被用到下一次迭代过程中)。
 85     """
 86     cap = cv.VideoCapture("../images/slow.mp4")
 87     ret, frame = cap.read()  # 获取第一帧
 88 
 89     # 设置初始窗口位置
 90     r, h, c, w = 210, 80, 300, 125  # r,c 左上角坐标,h,w 高宽
 91     track_window = (c, r, w, h)
 92 
 93     # 设置兴趣区域
 94     roi = frame[r:r + h, c:c + w]
 95 
 96     hsv_roi = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
 97 
 98     # 设置掩模,即剔除部分影响亮度的值
 99     mask = cv.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
100 
101     # 计算直方图
102     roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180])
103     cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)  # 归一化
104 
105     # 设置迭代条件,10次迭代,或至少移动一次
106     term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)
107 
108     while True:
109         ret, frame = cap.read()
110 
111         if ret is True:
112             hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
113             dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
114 
115             # 用meanShift算法获得新窗口,从而实现迭代
116             ret, track_window = cv.CamShift(dst, track_window, term_crit)
117             print(ret)
118 
119             # ret 为元组类型,分别为矩形左上角和右下角,以及旋转角度,
120             # 用boxPoints()和polylines()恰好可以画出这个旋转矩形
121             pts = cv.boxPoints(ret)
122             pts = np.int0(pts)
123             img2 = cv.polylines(frame, [pts], True, 255, 2)
124             cv.imshow('img2', img2)
125 
126             c = cv.waitKey(60) & 0xff
127             if c == 27:
128                 break
129             else:
130                 print(c)
131                 print(time.strftime('%H_%M_%S', time.localtime(time.time())))
132                 # cv.imwrite('../images/'+ time.strftime('%H_%M_%S', time.localtime(time.time())) + '.jpg', img2)
133         else:
134             break
135 
136 
137 def main():
138     # mean_shift_demo()
139     cam_shift_demo()
140     cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
141     cv.destroyAllWindows()  # 关闭所有窗口
142 
143 
144 if __name__ == '__main__':
145     main()
反向投影3
  1 import cv2 as cv
  2 import numpy as np
  3 
  4 # 由于目标对象或者摄像机的移动造成的图像对象在连续两帧图像中的移动 被称为光流。
  5 # 它是一个2D向量场,可以用来显示一个点从第一帧图像到第二 帧图像之间的移动。
  6 # 光流在很多领域中都很有用
  7 # • 由运动重建结构
  8 # • 视频压缩
  9 # • Video Stabilization 等
 10 #
 11 # 从使用者的角度来看,想法很简单,我们取跟踪一些点,然后我们就会获得这些点的光流向量。
 12 # 但是还有一些问题。直到现在我们处理的都是很小的运动。
 13 #  如果有大的运动怎么办呢?图像金字塔。我们可以使用图像金字塔的顶层,
 14 # 此时小的运动被移除,大的运动装换成了小的运动,现在再使用 Lucas-Kanade 算法,我们就会得到尺度空间上的光流。
 15 
 16 
 17 def optical_flow_demo():
 18     """
 19     函数目的:跟踪视频中的一些点。使用函数 cv2.goodFeatureToTrack()来确定要跟踪的点。
 20     首先在视频的第一帧图像中检测一些Shi-Tomasi角点,然后我们使用Lucas Kanade算法迭代跟踪这些角点。
 21     要给函数cv2.calcOpticlaFlowPyrLK()传入前一帧图像和其中的点,以及下一帧图像。
 22     函数将返回带有状态数的点, 如果状态数是 1,那说明在下一帧图像中找到了这个点(上一帧中角点),
 23     如果状态数是 0,就说明没有在下一帧图像中找到这个点。
 24     我们再把这些点作为参数传给函数,如此迭代下去实现跟踪。
 25     图像中的一些特征点甚至 在丢失以后,光流还会找到一个预期相似的点。
 26     所以为了实现稳定的跟踪,应该每个一定间隔就要进行一次角点检测。
 27     OpenCV 的官方示例中带有这样一个例子,它是每 5 帧进行一个特征点检测。
 28     它还对光流点使用反向检测来选取好的点进行跟踪
 29     """
 30     cap = cv.VideoCapture('../images/slow.mp4')
 31 
 32     # 用字典的方式传给goodFeaturesToTrack() 用来角点检测
 33     feature_params = dict( maxCorners = 100, qualityLevel = 0.3, minDistance = 7, blockSize = 7 )
 34 
 35     # maxLevel 为使用的图像金字塔层数
 36     lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
 37     # Create some random colors
 38     color = np.random.randint(0,255,(100,3))
 39 
 40     ret, old_frame = cap.read()
 41     old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
 42     p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
 43 
 44     mask = np.zeros_like(old_frame)
 45 
 46     while True:
 47         ret, frame = cap.read()
 48         frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
 49 
 50         # cv.calcOpticalFlowPyrLK()参数说明:前一帧图像,吼一帧图像,前一帧的特征点
 51         # 返回参数说明,后一帧对应的特征点,状态值(如果前一帧特征点在后一帧存在st=1,不存在st=0),err:前后帧特征点误差
 52         p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
 53 
 54         # 提取前后帧都存在的特征点
 55         good_new = p1[st == 1]
 56         good_old = p0[st == 1]
 57 
 58         for i, (new, old) in enumerate(zip(good_new, good_old)):  # zip打包函数
 59             a, b = new.ravel()  # 将特征点分解开,得到对应的坐标点
 60             c, d = old.ravel()
 61             mask = cv.line(mask, (a, b), (c, d), color[i].tolist(), 2)  # 随机获得线条,圆的颜色
 62             frame = cv.circle(frame, (a, b), 5, color[i].tolist(), -1)
 63         img = cv.add(frame, mask)
 64 
 65         cv.imshow("frame",img)
 66         k = cv.waitKey(30) & 0xff
 67         if k == 27:
 68             break
 69 
 70         old_gray = frame_gray.copy()
 71         p0 = good_new.reshape(-1, 1, 2)
 72 
 73     cv.destroyAllWindows()
 74     cap.release()
 75 
 76 
 77 def Farneback():
 78     """
 79     ucas-Kanade 法是计算一些特征点的光流。OpenCV 还提供了一种计算稠密光流的方法。
 80     它会图像中的所有点的光流。这是基于 Gunner_Farneback 的算法 (2003 年)。
 81     结果是一个带有光流向量 (u,v)的双通道数组。通过计算我们能得到光流的大小和方向。
 82     使用颜色对结果进行编码以便于更好的观察。
 83     方向对应于 H(Hue)通道,大小对应 于 V(Value)通道
 84     :return:
 85     """
 86     cap = cv.VideoCapture("../images/vtest.avi")
 87     ret, frame1 = cap.read()
 88     prvs = cv.cvtColor(frame1, cv.COLOR_BGR2GRAY)
 89     hsv = np.zeros_like(frame1)
 90     hsv[..., 1] = 255  # 将第二列都置为255
 91 
 92 
 93     while True:
 94         ret, frame2 = cap.read()
 95         next = cv.cvtColor(frame2,cv.COLOR_BGR2GRAY)
 96         flow = cv.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
 97 
 98         mag, ang = cv.cartToPolar(flow[..., 0], flow[..., 1])
 99         hsv[..., 0] = ang * 180 / np.pi / 2
100         hsv[..., 2] = cv.normalize(mag, None, 0, 255, cv.NORM_MINMAX)
101         rgb = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
102         cv.imshow('frame2', rgb)
103         k = cv.waitKey(30) & 0xff
104         if k == 27:
105             break
106         elif k == ord('s'):
107             cv.imwrite('../images/opticalfb.png', frame2)
108         cv.imwrite('../images/opticalhsv.png', rgb)
109         prvs = next
110 
111     cap.release()
112     cv.destroyAllWindows()
113 
114 
115 def main():
116     # optical_flow_demo()
117     Farneback()
118     cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
119     cv.destroyAllWindows()  # 关闭所有窗口
120 
121 
122 if __name__ == '__main__':
123     main()
反向投影4

3.模板匹配

 1 '''
 2     模板匹配
 3 '''
 4 import cv2 as cv
 5 import numpy as np
 6 
 7 
 8 # 模板匹配,就是在整个图像区域发现与给定子图像匹配的小块区域,
 9 # 需要模板图像T和待检测图像-源图像S
10 # 工作方法:在待检测的图像上,从左到右,从上倒下计算模板图像与重叠子图像匹配度,
11 # 匹配度越大,两者相同的可能性越大。
12 def template_demo():
13     tpl = cv.imread("../images/rabbit.jpg")
14     target = cv.imread("../images/CrystalLiu22.jpg")
15     cv.imshow("template", tpl)
16     cv.imshow("target", target)
17 
18     methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED]  # 三种模板匹配方法
19     th, tw = tpl.shape[:2]
20 
21     for md in methods:
22         print(md)
23         result = cv.matchTemplate(target, tpl, md)  # 得到匹配结果
24         min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
25         if md == cv.TM_SQDIFF_NORMED:  # cv.TM_SQDIFF_NORMED最小时最相似,其他最大时最相似
26             tl = min_loc
27         else:
28             tl = max_loc
29 
30         br = (tl[0] + tw, tl[1] + th)
31         cv.rectangle(target, tl, br, (0, 0, 255), 2)  # tl为左上角坐标,br为右下角坐标,从而画出矩形
32         cv.imshow("match-"+np.str(md), target)
33 
34 
35 if __name__ == '__main__':
36 
37     src = cv.imread("../images/CrystalLiu1.jpg")  # 读入图片放进src中
38     cv.namedWindow("Crystal Liu")  # 创建窗口
39     cv.imshow("Crystal Liu", src)  # 将src图片放入该创建的窗口中
40     template_demo()
41 
42     cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
43     cv.destroyAllWindows()  # 关闭所有窗口
模板匹配

 

posted @ 2020-06-14 21:05  liang哥哥  阅读(280)  评论(0)    收藏  举报