OpenCV计算机视觉实战 - 停车场车位识别【项目实战】(附完整代码)

#################################################################
纸上得来终觉浅,绝知此事要躬行
B站视频
新课件:https://pan.baidu.com/s/1frWHqCVGR2VTn5QBtW4lPA 提取码:xh02
老课件:https://pan.baidu.com/s/1Wi31FxSPBqWiuJX9quX-jA 提取码:bbfg
################################################################

任务描述:识别这种停车场图的 空车位被占用车位
识别流程:预处理 -> 获得车位坐标的字典 -> 训练VGG网络进行二分类
在这里插入图片描述

img_process 图像预处理过程

在这里插入图片描述

1.select_rgb_white_yellow 过滤背景(得到mask)

inRange(图,min阈值,max阈值) 小于min(大于max)的为0,min-max的为255
dst = cv.bitwise_and(src1, src2[, dst[, mask]]
src1:图1 src2:图2 mask:图1和图2’与’操作的掩码输出图像

def select_rgb_white_yellow(self,image): 
    # 过滤掉背景
    lower = np.uint8([120, 120, 120])
    upper = np.uint8([255, 255, 255])
    # lower_red和高于upper_red的部分分别变成0,lower_red~upper_red之间的值变成255,相当于过滤背景
    white_mask = cv2.inRange(image, lower, upper)
    self.cv_show('white_mask',white_mask)
masked <span class="token operator">=</span> cv2<span class="token punctuation">.</span>bitwise_and<span class="token punctuation">(</span>image<span class="token punctuation">,</span> image<span class="token punctuation">,</span> mask <span class="token operator">=</span> white_mask<span class="token punctuation">)</span>
self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'masked'</span><span class="token punctuation">,</span>masked<span class="token punctuation">)</span>
<span class="token keyword">return</span> masked
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述
在这里插入图片描述

2.convert_gray_scale # rgb转gray图

3.detect_edges # Canny检测

参考我的博客 https://blog.csdn.net/sinat_29950703/article/details/107651267

def convert_gray_scale(self,image):
    return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
def detect_edges(self,image, low_threshold=50, high_threshold=200):
    return cv2.Canny(image, low_threshold, high_threshold)

 
 
  • 1
  • 2
  • 3
  • 4

4.select_region # 针对当前任务手动指定区域

cv2.circle(img,中心点(x,y),半径r,color,粗细) 根据给定的圆心和半径等画圆 画出指定点

5.filter_region # 基于指定点剔除掉不需要的地方

np.zeros_like(img) # 生成一个跟img数组一样大小的 全0(黑)的数组
cv2.fillPoly(mask, vertices, 255) # 在mask上画多边形,由这vertices的点组成的,填充为白色
cv2.bitwise_and # 只在mask为255上才能留下来其他就过滤掉了

def filter_region(self,image, vertices):
    """
            剔除掉不需要的地方
    """
    mask = np.zeros_like(image)
    if len(mask.shape)==2:
        cv2.fillPoly(mask, vertices, 255)
        self.cv_show('mask', mask)    
    return cv2.bitwise_and(image, mask)

def select_region(self,image):
“”"
手动选择区域
“”"

# first, define the polygon by vertices
rows, cols = image.shape[:2]
pt_1 = [cols0.05, rows0.90]
pt_2 = [cols0.05, rows0.70]
pt_3 = [cols0.30, rows0.55]
pt_4 = [cols0.6, rows0.15]
pt_5 = [cols0.90, rows0.15]
pt_6 = [cols0.90, rows0.90]

vertices <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span>pt_1<span class="token punctuation">,</span> pt_2<span class="token punctuation">,</span> pt_3<span class="token punctuation">,</span> pt_4<span class="token punctuation">,</span> pt_5<span class="token punctuation">,</span> pt_6<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> dtype<span class="token operator">=</span>np<span class="token punctuation">.</span>int32<span class="token punctuation">)</span> 
point_img <span class="token operator">=</span> image<span class="token punctuation">.</span>copy<span class="token punctuation">(</span><span class="token punctuation">)</span>       
point_img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>cvtColor<span class="token punctuation">(</span>point_img<span class="token punctuation">,</span> cv2<span class="token punctuation">.</span>COLOR_GRAY2RGB<span class="token punctuation">)</span>
<span class="token keyword">for</span> point <span class="token keyword">in</span> vertices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">:</span>
    cv2<span class="token punctuation">.</span>circle<span class="token punctuation">(</span>point_img<span class="token punctuation">,</span> <span class="token punctuation">(</span>point<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>point<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span>
self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'point_img'</span><span class="token punctuation">,</span>point_img<span class="token punctuation">)</span>

<span class="token keyword">return</span> self<span class="token punctuation">.</span>filter_region<span class="token punctuation">(</span>image<span class="token punctuation">,</span> vertices<span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

在这里插入图片描述
在这里插入图片描述

6.hough_lines # 找直线

HoughLinesP函数是统计概率霍夫线变换函数,该函数能输出检测到的直线的端点 (x_{0}, y_{0}, x_{1}, y_{1}),
其函数原型为:HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]]) -> lines
cv2.HoughLinesP(边缘检测后的二值图) 统计概率霍夫线变换函数

7.draw_lines # 过滤线

abs(y2-y1) <=1 不要斜线
abs(x2-x1) >=25 and abs(x2-x1) <= 55 长度太长的也不要

def hough_lines(self,image):
    # 输入的图像需要是边缘检测后的结果
    # minLineLengh(线的最短长度,比这个短的都被忽略)和MaxLineCap(两条直线之间的最大间隔,小于此值,认为是一条直线)
    # rho距离精度,theta角度精度,threshod超过设定阈值才被检测出线段
    return cv2.HoughLinesP(image, rho=0.1, theta=np.pi/10, threshold=15, minLineLength=9, maxLineGap=4)

def draw_lines(self,image, lines, color=[255, 0, 0], thickness=2, make_copy=True):
# 过滤霍夫变换检测到直线
if make_copy:
image = np.copy(image)
cleaned = []
for line in lines:
for x1,y1,x2,y2 in line:
if abs(y2-y1) <=1 and abs(x2-x1) >=25 and abs(x2-x1) <= 55:
cleaned.append((x1,y1,x2,y2))
cv2.line(image, (x1, y1), (x2, y2), color, thickness)
print(" No lines detected: ", len(cleaned))
return image

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

8.identify_blocks # 区域划分

step 3: 指定行间距小于10的,划分为不同的列,共12簇

def identify_blocks(self,image, lines, make_copy=True):
    if make_copy:
        new_image = np.copy(image)
    #Step 1: 过滤部分直线
    cleaned = []
    for line in lines:
        for x1,y1,x2,y2 in line:
            if abs(y2-y1) <=1 and abs(x2-x1) >=25 and abs(x2-x1) <= 55:
                cleaned.append((x1,y1,x2,y2))
<span class="token comment">#Step 2: 对直线按照x1进行排序</span>
<span class="token keyword">import</span> operator
list1 <span class="token operator">=</span> <span class="token builtin">sorted</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">,</span> key<span class="token operator">=</span>operator<span class="token punctuation">.</span>itemgetter<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

<span class="token comment">#Step 3: 找到多个列,相当于每列是一排车</span>
clusters <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
dIndex <span class="token operator">=</span> <span class="token number">0</span>
clus_dist <span class="token operator">=</span> <span class="token number">10</span>

<span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>list1<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    distance <span class="token operator">=</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>list1<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">-</span> list1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> distance <span class="token operator">&lt;=</span> clus_dist<span class="token punctuation">:</span>
        <span class="token keyword">if</span> <span class="token operator">not</span> dIndex <span class="token keyword">in</span> clusters<span class="token punctuation">.</span>keys<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> clusters<span class="token punctuation">[</span>dIndex<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
        clusters<span class="token punctuation">[</span>dIndex<span class="token punctuation">]</span><span class="token punctuation">.</span>append<span class="token punctuation">(</span>list1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span>
        clusters<span class="token punctuation">[</span>dIndex<span class="token punctuation">]</span><span class="token punctuation">.</span>append<span class="token punctuation">(</span>list1<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> 

    <span class="token keyword">else</span><span class="token punctuation">:</span>
        dIndex <span class="token operator">+=</span> <span class="token number">1</span>

<span class="token comment">#Step 4: 得到坐标</span>
rects <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
i <span class="token operator">=</span> <span class="token number">0</span>
<span class="token keyword">for</span> key <span class="token keyword">in</span> clusters<span class="token punctuation">:</span>
    all_list <span class="token operator">=</span> clusters<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
    cleaned <span class="token operator">=</span> <span class="token builtin">list</span><span class="token punctuation">(</span><span class="token builtin">set</span><span class="token punctuation">(</span>all_list<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">5</span><span class="token punctuation">:</span>
        cleaned <span class="token operator">=</span> <span class="token builtin">sorted</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">,</span> key<span class="token operator">=</span><span class="token keyword">lambda</span> tup<span class="token punctuation">:</span> tup<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
        avg_y1 <span class="token operator">=</span> cleaned<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
        avg_y2 <span class="token operator">=</span> cleaned<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
        avg_x1 <span class="token operator">=</span> <span class="token number">0</span>
        avg_x2 <span class="token operator">=</span> <span class="token number">0</span>
        <span class="token keyword">for</span> tup <span class="token keyword">in</span> cleaned<span class="token punctuation">:</span>
            avg_x1 <span class="token operator">+=</span> tup<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
            avg_x2 <span class="token operator">+=</span> tup<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span>
        avg_x1 <span class="token operator">=</span> avg_x1<span class="token operator">/</span><span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span>
        avg_x2 <span class="token operator">=</span> avg_x2<span class="token operator">/</span><span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span>
        rects<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>avg_x1<span class="token punctuation">,</span> avg_y1<span class="token punctuation">,</span> avg_x2<span class="token punctuation">,</span> avg_y2<span class="token punctuation">)</span>
        i <span class="token operator">+=</span> <span class="token number">1</span>

<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"Num Parking Lanes: "</span><span class="token punctuation">,</span> <span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment">#Step 5: 把列矩形画出来</span>
buff <span class="token operator">=</span> <span class="token number">7</span>
<span class="token keyword">for</span> key <span class="token keyword">in</span> rects<span class="token punctuation">:</span>
    tup_topLeft <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">-</span> buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    tup_botRight <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">+</span> buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> tup_topLeft<span class="token punctuation">,</span>tup_botRight<span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">255</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> new_image<span class="token punctuation">,</span> rects
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 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
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

在这里插入图片描述

9.draw_parking

根据上一步切分的列,得到坐标。根据纵坐标的间距不断切分停车位,车位间距gap为15.5
(y2-y1)/gap表示能停多少辆车

def draw_parking(self,image, rects, make_copy = True, color=[255, 0, 0], thickness=2, save = True):
    if make_copy:
        new_image = np.copy(image)
    gap = 15.5
    spot_dict = {} # 字典:一个车位对应一个位置
    tot_spots = 0
    # 微调
    adj_y1 = {0: 20, 1:-10, 2:0, 3:-11, 4:28, 5:5, 6:-15, 7:-15, 8:-10, 9:-30, 10:9, 11:-32}
    adj_y2 = {0: 30, 1: 50, 2:15, 3:10, 4:-15, 5:15, 6:15, 7:-20, 8:15, 9:15, 10:0, 11:30}
adj_x1 <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token operator">-</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">}</span>
adj_x2 <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span> <span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">}</span>
<span class="token comment"># 继续微调</span>
<span class="token keyword">for</span> key <span class="token keyword">in</span> rects<span class="token punctuation">:</span>
    tup <span class="token operator">=</span> rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
    x1 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">+</span> adj_x1<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
    x2 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator">+</span> adj_x2<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
    y1 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">+</span> adj_y1<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
    y2 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">+</span> adj_y2<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
    cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span>x2<span class="token punctuation">,</span>y2<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">255</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span>
    <span class="token comment"># (y2-y1)//gap表示能停多少辆车</span>
    num_splits <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token builtin">abs</span><span class="token punctuation">(</span>y2<span class="token operator">-</span>y1<span class="token punctuation">)</span><span class="token operator">//</span>gap<span class="token punctuation">)</span>
    <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num_splits<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        y <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1 <span class="token operator">+</span> i<span class="token operator">*</span>gap<span class="token punctuation">)</span>
        cv2<span class="token punctuation">.</span>line<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>x2<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> thickness<span class="token punctuation">)</span>
    <span class="token keyword">if</span> key <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">and</span> key <span class="token operator">&lt;</span> <span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token punctuation">:</span>        
        <span class="token comment">#竖直线</span>
        x <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x1 <span class="token operator">+</span> x2<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">2</span><span class="token punctuation">)</span>
        cv2<span class="token punctuation">.</span>line<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y2<span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> thickness<span class="token punctuation">)</span>
    <span class="token comment"># 计算数量</span>
    <span class="token keyword">if</span> key <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">or</span> key <span class="token operator">==</span> <span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        tot_spots <span class="token operator">+=</span> num_splits <span class="token operator">+</span><span class="token number">1</span>
    <span class="token keyword">else</span><span class="token punctuation">:</span>
        tot_spots <span class="token operator">+=</span> <span class="token number">2</span><span class="token operator">*</span><span class="token punctuation">(</span>num_splits <span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span>  <span class="token comment"># 双排的乘2</span>
        
    <span class="token comment"># 字典对应好</span>
    <span class="token keyword">if</span> key <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">or</span> key <span class="token operator">==</span> <span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num_splits<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
            cur_len <span class="token operator">=</span> <span class="token builtin">len</span><span class="token punctuation">(</span>spot_dict<span class="token punctuation">)</span>
            y <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1 <span class="token operator">+</span> i<span class="token operator">*</span>gap<span class="token punctuation">)</span>
            spot_dict<span class="token punctuation">[</span><span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y<span class="token operator">+</span>gap<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> cur_len <span class="token operator">+</span><span class="token number">1</span>        
    <span class="token keyword">else</span><span class="token punctuation">:</span>
        <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num_splits<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
            cur_len <span class="token operator">=</span> <span class="token builtin">len</span><span class="token punctuation">(</span>spot_dict<span class="token punctuation">)</span>
            y <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1 <span class="token operator">+</span> i<span class="token operator">*</span>gap<span class="token punctuation">)</span>
            x <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x1 <span class="token operator">+</span> x2<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">2</span><span class="token punctuation">)</span>
            spot_dict<span class="token punctuation">[</span><span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token operator">+</span>gap<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> cur_len <span class="token operator">+</span><span class="token number">1</span>
            spot_dict<span class="token punctuation">[</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y<span class="token operator">+</span>gap<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> cur_len <span class="token operator">+</span><span class="token number">2</span>   

<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"total parking spaces: "</span><span class="token punctuation">,</span> tot_spots<span class="token punctuation">,</span> cur_len<span class="token punctuation">)</span>
<span class="token keyword">if</span> save<span class="token punctuation">:</span>
    filename <span class="token operator">=</span> <span class="token string">'with_parking.jpg'</span>
    cv2<span class="token punctuation">.</span>imwrite<span class="token punctuation">(</span>filename<span class="token punctuation">,</span> new_image<span class="token punctuation">)</span>
<span class="token keyword">return</span> new_image<span class="token punctuation">,</span> spot_dict 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 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
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

在这里插入图片描述

save_images_for_cnn 保存所有切割出来的图片

非必须的步骤,主要是要获得车位坐标的字典

def save_images_for_cnn(self,image, spot_dict, folder_name ='cnn_data'):
    for spot in spot_dict.keys():
        (x1, y1, x2, y2) = spot
        (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))
        #裁剪
        spot_img = image[y1:y2, x1:x2]
        spot_img = cv2.resize(spot_img, (0,0), fx=2.0, fy=2.0) 
        spot_id = spot_dict[spot]
    filename <span class="token operator">=</span> <span class="token string">'spot'</span> <span class="token operator">+</span> <span class="token builtin">str</span><span class="token punctuation">(</span>spot_id<span class="token punctuation">)</span> <span class="token operator">+</span><span class="token string">'.jpg'</span>
    <span class="token keyword">print</span><span class="token punctuation">(</span>spot_img<span class="token punctuation">.</span>shape<span class="token punctuation">,</span> filename<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span>x2<span class="token punctuation">,</span>y1<span class="token punctuation">,</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
    
    cv2<span class="token punctuation">.</span>imwrite<span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>folder_name<span class="token punctuation">,</span> filename<span class="token punctuation">)</span><span class="token punctuation">,</span> spot_img<span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

主函数

final_spot_dict 是img_process函数 return的车位坐标字典

if __name__ == '__main__':
    test_images = [plt.imread(path) for path in glob.glob('test_images/*.jpg')]
    weights_path = 'car1.h5'
    video_name = 'parking_video.mp4'
    class_dictionary = {}
    class_dictionary[0] = 'empty'
    class_dictionary[1] = 'occupied'
park <span class="token operator">=</span> Parking<span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment"># 实例化Parking对象</span>
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>test_images<span class="token punctuation">)</span>
final_spot_dict <span class="token operator">=</span> img_process<span class="token punctuation">(</span>test_images<span class="token punctuation">,</span>park<span class="token punctuation">)</span> <span class="token comment"># 图像处理</span>
model <span class="token operator">=</span> keras_model<span class="token punctuation">(</span>weights_path<span class="token punctuation">)</span>
img_test<span class="token punctuation">(</span>test_images<span class="token punctuation">,</span>final_spot_dict<span class="token punctuation">,</span>model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">)</span>
video_test<span class="token punctuation">(</span>video_name<span class="token punctuation">,</span>final_spot_dict<span class="token punctuation">,</span>model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

其中 h5文件 是已训练好的二分类车位的权重,调用即可进行分类
关于深度学习的知识就不赘述了
在这里插入图片描述

附:完整代码

park.py

from __future__ import division
import matplotlib.pyplot as plt
import cv2
import os, glob
import numpy as np
from PIL import Image
from keras.applications.imagenet_utils import preprocess_input
from keras.models import load_model
from keras.preprocessing import image
from Parking import Parking
import pickle
cwd = os.getcwd()

def img_process(test_images,park):
white_yellow_images = list(map(park.select_rgb_white_yellow, test_images))
park.show_images(white_yellow_images)

gray_images <span class="token operator">=</span> <span class="token builtin">list</span><span class="token punctuation">(</span><span class="token builtin">map</span><span class="token punctuation">(</span>park<span class="token punctuation">.</span>convert_gray_scale<span class="token punctuation">,</span> white_yellow_images<span class="token punctuation">)</span><span class="token punctuation">)</span>
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>gray_images<span class="token punctuation">)</span>

edge_images <span class="token operator">=</span> <span class="token builtin">list</span><span class="token punctuation">(</span><span class="token builtin">map</span><span class="token punctuation">(</span><span class="token keyword">lambda</span> image<span class="token punctuation">:</span> park<span class="token punctuation">.</span>detect_edges<span class="token punctuation">(</span>image<span class="token punctuation">)</span><span class="token punctuation">,</span> gray_images<span class="token punctuation">)</span><span class="token punctuation">)</span>
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>edge_images<span class="token punctuation">)</span>

roi_images <span class="token operator">=</span> <span class="token builtin">list</span><span class="token punctuation">(</span><span class="token builtin">map</span><span class="token punctuation">(</span>park<span class="token punctuation">.</span>select_region<span class="token punctuation">,</span> edge_images<span class="token punctuation">)</span><span class="token punctuation">)</span>
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>roi_images<span class="token punctuation">)</span>

list_of_lines <span class="token operator">=</span> <span class="token builtin">list</span><span class="token punctuation">(</span><span class="token builtin">map</span><span class="token punctuation">(</span>park<span class="token punctuation">.</span>hough_lines<span class="token punctuation">,</span> roi_images<span class="token punctuation">)</span><span class="token punctuation">)</span>

line_images <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token keyword">for</span> image<span class="token punctuation">,</span> lines <span class="token keyword">in</span> <span class="token builtin">zip</span><span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> list_of_lines<span class="token punctuation">)</span><span class="token punctuation">:</span>
    line_images<span class="token punctuation">.</span>append<span class="token punctuation">(</span>park<span class="token punctuation">.</span>draw_lines<span class="token punctuation">(</span>image<span class="token punctuation">,</span> lines<span class="token punctuation">)</span><span class="token punctuation">)</span> 
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>line_images<span class="token punctuation">)</span>

rect_images <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
rect_coords <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>    <span class="token comment"># 区域置空</span>
<span class="token keyword">for</span> image<span class="token punctuation">,</span> lines <span class="token keyword">in</span> <span class="token builtin">zip</span><span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> list_of_lines<span class="token punctuation">)</span><span class="token punctuation">:</span>
    new_image<span class="token punctuation">,</span> rects <span class="token operator">=</span> park<span class="token punctuation">.</span>identify_blocks<span class="token punctuation">(</span>image<span class="token punctuation">,</span> lines<span class="token punctuation">)</span>
    rect_images<span class="token punctuation">.</span>append<span class="token punctuation">(</span>new_image<span class="token punctuation">)</span>
    rect_coords<span class="token punctuation">.</span>append<span class="token punctuation">(</span>rects<span class="token punctuation">)</span>
    
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>rect_images<span class="token punctuation">)</span>

delineated <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
spot_pos <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token keyword">for</span> image<span class="token punctuation">,</span> rects <span class="token keyword">in</span> <span class="token builtin">zip</span><span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> rect_coords<span class="token punctuation">)</span><span class="token punctuation">:</span>
    new_image<span class="token punctuation">,</span> spot_dict <span class="token operator">=</span> park<span class="token punctuation">.</span>draw_parking<span class="token punctuation">(</span>image<span class="token punctuation">,</span> rects<span class="token punctuation">)</span>
    delineated<span class="token punctuation">.</span>append<span class="token punctuation">(</span>new_image<span class="token punctuation">)</span>
    spot_pos<span class="token punctuation">.</span>append<span class="token punctuation">(</span>spot_dict<span class="token punctuation">)</span>
    
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>delineated<span class="token punctuation">)</span>
final_spot_dict <span class="token operator">=</span> spot_pos<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>final_spot_dict<span class="token punctuation">)</span><span class="token punctuation">)</span>

<span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span><span class="token string">'spot_dict.pickle'</span><span class="token punctuation">,</span> <span class="token string">'wb'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> handle<span class="token punctuation">:</span>
    pickle<span class="token punctuation">.</span>dump<span class="token punctuation">(</span>final_spot_dict<span class="token punctuation">,</span> handle<span class="token punctuation">,</span> protocol<span class="token operator">=</span>pickle<span class="token punctuation">.</span>HIGHEST_PROTOCOL<span class="token punctuation">)</span>
<span class="token comment"># park.save_images_for_cnn(test_images[0],final_spot_dict)</span>

<span class="token keyword">return</span> final_spot_dict

def keras_model(weights_path):
model = load_model(weights_path)
return model
def img_test(test_images,final_spot_dict,model,class_dictionary):
for i in range (len(test_images)):
predicted_images = park.predict_on_image(test_images[i],final_spot_dict,model,class_dictionary)
def video_test(video_name,final_spot_dict,model,class_dictionary):
name = video_name
cap = cv2.VideoCapture(name)
park.predict_on_video(name,final_spot_dict,model,class_dictionary,ret=True)

if name == main:
test_images = [plt.imread(path) for path in glob.glob(‘test_images/*.jpg’)]
weights_path = ‘car1.h5’
video_name = ‘parking_video.mp4’
class_dictionary = { }
class_dictionary[0] = ‘empty’
class_dictionary[1] = ‘occupied’

park <span class="token operator">=</span> Parking<span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment"># 实例化Parking对象</span>
park<span class="token punctuation">.</span>show_images<span class="token punctuation">(</span>test_images<span class="token punctuation">)</span>
final_spot_dict <span class="token operator">=</span> img_process<span class="token punctuation">(</span>test_images<span class="token punctuation">,</span>park<span class="token punctuation">)</span> <span class="token comment"># 图像处理</span>
model <span class="token operator">=</span> keras_model<span class="token punctuation">(</span>weights_path<span class="token punctuation">)</span>
img_test<span class="token punctuation">(</span>test_images<span class="token punctuation">,</span>final_spot_dict<span class="token punctuation">,</span>model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">)</span>
<span class="token comment"># video_test(video_name,final_spot_dict,model,class_dictionary)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 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
  • 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
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

Parking.py

import matplotlib.pyplot as plt
import cv2
import os, glob
import numpy as np
# 要用的函数封装在Parking中了
class Parking:
<span class="token keyword">def</span> <span class="token function">show_images</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> images<span class="token punctuation">,</span> cmap<span class="token operator">=</span><span class="token boolean">None</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    cols <span class="token operator">=</span> <span class="token number">2</span>
    rows <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>images<span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">//</span>cols
    
    plt<span class="token punctuation">.</span>figure<span class="token punctuation">(</span>figsize<span class="token operator">=</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">for</span> i<span class="token punctuation">,</span> image <span class="token keyword">in</span> <span class="token builtin">enumerate</span><span class="token punctuation">(</span>images<span class="token punctuation">)</span><span class="token punctuation">:</span>
        plt<span class="token punctuation">.</span>subplot<span class="token punctuation">(</span>rows<span class="token punctuation">,</span> cols<span class="token punctuation">,</span> i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span>
        cmap <span class="token operator">=</span> <span class="token string">'gray'</span> <span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>image<span class="token punctuation">.</span>shape<span class="token punctuation">)</span><span class="token operator">==</span><span class="token number">2</span> <span class="token keyword">else</span> cmap
        plt<span class="token punctuation">.</span>imshow<span class="token punctuation">(</span>image<span class="token punctuation">,</span> cmap<span class="token operator">=</span>cmap<span class="token punctuation">)</span>
        plt<span class="token punctuation">.</span>xticks<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
        plt<span class="token punctuation">.</span>yticks<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
    plt<span class="token punctuation">.</span>tight_layout<span class="token punctuation">(</span>pad<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">,</span> h_pad<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">,</span> w_pad<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">)</span>
    plt<span class="token punctuation">.</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">cv_show</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>name<span class="token punctuation">,</span>img<span class="token punctuation">)</span><span class="token punctuation">:</span>
    cv2<span class="token punctuation">.</span>imshow<span class="token punctuation">(</span>name<span class="token punctuation">,</span> img<span class="token punctuation">)</span>
    cv2<span class="token punctuation">.</span>waitKey<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
    cv2<span class="token punctuation">.</span>destroyAllWindows<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">select_rgb_white_yellow</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">)</span><span class="token punctuation">:</span> 
    <span class="token comment"># 过滤掉背景</span>
    lower <span class="token operator">=</span> np<span class="token punctuation">.</span>uint8<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">120</span><span class="token punctuation">,</span> <span class="token number">120</span><span class="token punctuation">,</span> <span class="token number">120</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
    upper <span class="token operator">=</span> np<span class="token punctuation">.</span>uint8<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
    <span class="token comment"># lower_red和高于upper_red的部分分别变成0,lower_red~upper_red之间的值变成255,相当于过滤背景</span>
    white_mask <span class="token operator">=</span> cv2<span class="token punctuation">.</span>inRange<span class="token punctuation">(</span>image<span class="token punctuation">,</span> lower<span class="token punctuation">,</span> upper<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'white_mask'</span><span class="token punctuation">,</span>white_mask<span class="token punctuation">)</span>
    
    masked <span class="token operator">=</span> cv2<span class="token punctuation">.</span>bitwise_and<span class="token punctuation">(</span>image<span class="token punctuation">,</span> image<span class="token punctuation">,</span> mask <span class="token operator">=</span> white_mask<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'masked'</span><span class="token punctuation">,</span>masked<span class="token punctuation">)</span>
    <span class="token keyword">return</span> masked
<span class="token keyword">def</span> <span class="token function">convert_gray_scale</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> cv2<span class="token punctuation">.</span>cvtColor<span class="token punctuation">(</span>image<span class="token punctuation">,</span> cv2<span class="token punctuation">.</span>COLOR_RGB2GRAY<span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">detect_edges</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> low_threshold<span class="token operator">=</span><span class="token number">50</span><span class="token punctuation">,</span> high_threshold<span class="token operator">=</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> cv2<span class="token punctuation">.</span>Canny<span class="token punctuation">(</span>image<span class="token punctuation">,</span> low_threshold<span class="token punctuation">,</span> high_threshold<span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">filter_region</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> vertices<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""
            剔除掉不需要的地方
    """</span>
    mask <span class="token operator">=</span> np<span class="token punctuation">.</span>zeros_like<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>mask<span class="token punctuation">.</span>shape<span class="token punctuation">)</span><span class="token operator">==</span><span class="token number">2</span><span class="token punctuation">:</span>
        cv2<span class="token punctuation">.</span>fillPoly<span class="token punctuation">(</span>mask<span class="token punctuation">,</span> vertices<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span>
        self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'mask'</span><span class="token punctuation">,</span> mask<span class="token punctuation">)</span>    
    <span class="token keyword">return</span> cv2<span class="token punctuation">.</span>bitwise_and<span class="token punctuation">(</span>image<span class="token punctuation">,</span> mask<span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">select_region</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token triple-quoted-string string">"""
            手动选择区域
    """</span>
    <span class="token comment"># first, define the polygon by vertices</span>
    rows<span class="token punctuation">,</span> cols <span class="token operator">=</span> image<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token number">2</span><span class="token punctuation">]</span>
    pt_1  <span class="token operator">=</span> <span class="token punctuation">[</span>cols<span class="token operator">*</span><span class="token number">0.05</span><span class="token punctuation">,</span> rows<span class="token operator">*</span><span class="token number">0.90</span><span class="token punctuation">]</span>
    pt_2 <span class="token operator">=</span> <span class="token punctuation">[</span>cols<span class="token operator">*</span><span class="token number">0.05</span><span class="token punctuation">,</span> rows<span class="token operator">*</span><span class="token number">0.70</span><span class="token punctuation">]</span>
    pt_3 <span class="token operator">=</span> <span class="token punctuation">[</span>cols<span class="token operator">*</span><span class="token number">0.30</span><span class="token punctuation">,</span> rows<span class="token operator">*</span><span class="token number">0.55</span><span class="token punctuation">]</span>
    pt_4 <span class="token operator">=</span> <span class="token punctuation">[</span>cols<span class="token operator">*</span><span class="token number">0.6</span><span class="token punctuation">,</span> rows<span class="token operator">*</span><span class="token number">0.15</span><span class="token punctuation">]</span>
    pt_5 <span class="token operator">=</span> <span class="token punctuation">[</span>cols<span class="token operator">*</span><span class="token number">0.90</span><span class="token punctuation">,</span> rows<span class="token operator">*</span><span class="token number">0.15</span><span class="token punctuation">]</span> 
    pt_6 <span class="token operator">=</span> <span class="token punctuation">[</span>cols<span class="token operator">*</span><span class="token number">0.90</span><span class="token punctuation">,</span> rows<span class="token operator">*</span><span class="token number">0.90</span><span class="token punctuation">]</span>

    vertices <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span>pt_1<span class="token punctuation">,</span> pt_2<span class="token punctuation">,</span> pt_3<span class="token punctuation">,</span> pt_4<span class="token punctuation">,</span> pt_5<span class="token punctuation">,</span> pt_6<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> dtype<span class="token operator">=</span>np<span class="token punctuation">.</span>int32<span class="token punctuation">)</span> 
    point_img <span class="token operator">=</span> image<span class="token punctuation">.</span>copy<span class="token punctuation">(</span><span class="token punctuation">)</span>       
    point_img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>cvtColor<span class="token punctuation">(</span>point_img<span class="token punctuation">,</span> cv2<span class="token punctuation">.</span>COLOR_GRAY2RGB<span class="token punctuation">)</span>
    <span class="token keyword">for</span> point <span class="token keyword">in</span> vertices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">:</span>
        cv2<span class="token punctuation">.</span>circle<span class="token punctuation">(</span>point_img<span class="token punctuation">,</span> <span class="token punctuation">(</span>point<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>point<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'point_img'</span><span class="token punctuation">,</span>point_img<span class="token punctuation">)</span>
    
    <span class="token keyword">return</span> self<span class="token punctuation">.</span>filter_region<span class="token punctuation">(</span>image<span class="token punctuation">,</span> vertices<span class="token punctuation">)</span>

<span class="token keyword">def</span> <span class="token function">hough_lines</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token comment"># 输入的图像需要是边缘检测后的结果</span>
    <span class="token comment"># minLineLengh(线的最短长度,比这个短的都被忽略)和MaxLineCap(两条直线之间的最大间隔,小于此值,认为是一条直线)</span>
    <span class="token comment"># rho距离精度,theta角度精度,threshod超过设定阈值才被检测出线段</span>
    <span class="token keyword">return</span> cv2<span class="token punctuation">.</span>HoughLinesP<span class="token punctuation">(</span>image<span class="token punctuation">,</span> rho<span class="token operator">=</span><span class="token number">0.1</span><span class="token punctuation">,</span> theta<span class="token operator">=</span>np<span class="token punctuation">.</span>pi<span class="token operator">/</span><span class="token number">10</span><span class="token punctuation">,</span> threshold<span class="token operator">=</span><span class="token number">15</span><span class="token punctuation">,</span> minLineLength<span class="token operator">=</span><span class="token number">9</span><span class="token punctuation">,</span> maxLineGap<span class="token operator">=</span><span class="token number">4</span><span class="token punctuation">)</span>
    
<span class="token keyword">def</span> <span class="token function">draw_lines</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> lines<span class="token punctuation">,</span> color<span class="token operator">=</span><span class="token punctuation">[</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> thickness<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">,</span> make_copy<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token comment"># 过滤霍夫变换检测到直线</span>
    <span class="token keyword">if</span> make_copy<span class="token punctuation">:</span>
        image <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span> 
    cleaned <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> line <span class="token keyword">in</span> lines<span class="token punctuation">:</span>
        <span class="token keyword">for</span> x1<span class="token punctuation">,</span>y1<span class="token punctuation">,</span>x2<span class="token punctuation">,</span>y2 <span class="token keyword">in</span> line<span class="token punctuation">:</span>
            <span class="token keyword">if</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>y2<span class="token operator">-</span>y1<span class="token punctuation">)</span> <span class="token operator">&lt;=</span><span class="token number">1</span> <span class="token operator">and</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>x2<span class="token operator">-</span>x1<span class="token punctuation">)</span> <span class="token operator">&gt;=</span><span class="token number">25</span> <span class="token operator">and</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>x2<span class="token operator">-</span>x1<span class="token punctuation">)</span> <span class="token operator">&lt;=</span> <span class="token number">55</span><span class="token punctuation">:</span>
                cleaned<span class="token punctuation">.</span>append<span class="token punctuation">(</span><span class="token punctuation">(</span>x1<span class="token punctuation">,</span>y1<span class="token punctuation">,</span>x2<span class="token punctuation">,</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
                cv2<span class="token punctuation">.</span>line<span class="token punctuation">(</span>image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> thickness<span class="token punctuation">)</span>
    <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">" No lines detected: "</span><span class="token punctuation">,</span> <span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> image

<span class="token keyword">def</span> <span class="token function">identify_blocks</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> lines<span class="token punctuation">,</span> make_copy<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span> make_copy<span class="token punctuation">:</span>
        new_image <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
    <span class="token comment">#Step 1: 过滤部分直线</span>
    cleaned <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> line <span class="token keyword">in</span> lines<span class="token punctuation">:</span>
        <span class="token keyword">for</span> x1<span class="token punctuation">,</span>y1<span class="token punctuation">,</span>x2<span class="token punctuation">,</span>y2 <span class="token keyword">in</span> line<span class="token punctuation">:</span>
            <span class="token keyword">if</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>y2<span class="token operator">-</span>y1<span class="token punctuation">)</span> <span class="token operator">&lt;=</span><span class="token number">1</span> <span class="token operator">and</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>x2<span class="token operator">-</span>x1<span class="token punctuation">)</span> <span class="token operator">&gt;=</span><span class="token number">25</span> <span class="token operator">and</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>x2<span class="token operator">-</span>x1<span class="token punctuation">)</span> <span class="token operator">&lt;=</span> <span class="token number">55</span><span class="token punctuation">:</span>
                cleaned<span class="token punctuation">.</span>append<span class="token punctuation">(</span><span class="token punctuation">(</span>x1<span class="token punctuation">,</span>y1<span class="token punctuation">,</span>x2<span class="token punctuation">,</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
    
    <span class="token comment">#Step 2: 对直线按照x1进行排序</span>
    <span class="token keyword">import</span> operator
    list1 <span class="token operator">=</span> <span class="token builtin">sorted</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">,</span> key<span class="token operator">=</span>operator<span class="token punctuation">.</span>itemgetter<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    
    <span class="token comment">#Step 3: 找到多个列,相当于每列是一排车</span>
    clusters <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
    dIndex <span class="token operator">=</span> <span class="token number">0</span>
    clus_dist <span class="token operator">=</span> <span class="token number">10</span>

    <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>list1<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        distance <span class="token operator">=</span> <span class="token builtin">abs</span><span class="token punctuation">(</span>list1<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">-</span> list1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
        <span class="token keyword">if</span> distance <span class="token operator">&lt;=</span> clus_dist<span class="token punctuation">:</span>
            <span class="token keyword">if</span> <span class="token operator">not</span> dIndex <span class="token keyword">in</span> clusters<span class="token punctuation">.</span>keys<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> clusters<span class="token punctuation">[</span>dIndex<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
            clusters<span class="token punctuation">[</span>dIndex<span class="token punctuation">]</span><span class="token punctuation">.</span>append<span class="token punctuation">(</span>list1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span>
            clusters<span class="token punctuation">[</span>dIndex<span class="token punctuation">]</span><span class="token punctuation">.</span>append<span class="token punctuation">(</span>list1<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> 

        <span class="token keyword">else</span><span class="token punctuation">:</span>
            dIndex <span class="token operator">+=</span> <span class="token number">1</span>
    
    <span class="token comment">#Step 4: 得到坐标</span>
    rects <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
    i <span class="token operator">=</span> <span class="token number">0</span>
    <span class="token keyword">for</span> key <span class="token keyword">in</span> clusters<span class="token punctuation">:</span>
        all_list <span class="token operator">=</span> clusters<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
        cleaned <span class="token operator">=</span> <span class="token builtin">list</span><span class="token punctuation">(</span><span class="token builtin">set</span><span class="token punctuation">(</span>all_list<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">5</span><span class="token punctuation">:</span>
            cleaned <span class="token operator">=</span> <span class="token builtin">sorted</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">,</span> key<span class="token operator">=</span><span class="token keyword">lambda</span> tup<span class="token punctuation">:</span> tup<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
            avg_y1 <span class="token operator">=</span> cleaned<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
            avg_y2 <span class="token operator">=</span> cleaned<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
            avg_x1 <span class="token operator">=</span> <span class="token number">0</span>
            avg_x2 <span class="token operator">=</span> <span class="token number">0</span>
            <span class="token keyword">for</span> tup <span class="token keyword">in</span> cleaned<span class="token punctuation">:</span>
                avg_x1 <span class="token operator">+=</span> tup<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
                avg_x2 <span class="token operator">+=</span> tup<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span>
            avg_x1 <span class="token operator">=</span> avg_x1<span class="token operator">/</span><span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span>
            avg_x2 <span class="token operator">=</span> avg_x2<span class="token operator">/</span><span class="token builtin">len</span><span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span>
            rects<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>avg_x1<span class="token punctuation">,</span> avg_y1<span class="token punctuation">,</span> avg_x2<span class="token punctuation">,</span> avg_y2<span class="token punctuation">)</span>
            i <span class="token operator">+=</span> <span class="token number">1</span>
    
    <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"Num Parking Lanes: "</span><span class="token punctuation">,</span> <span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token comment">#Step 5: 把列矩形画出来</span>
    buff <span class="token operator">=</span> <span class="token number">7</span>
    <span class="token keyword">for</span> key <span class="token keyword">in</span> rects<span class="token punctuation">:</span>
        tup_topLeft <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">-</span> buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        tup_botRight <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">+</span> buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> tup_topLeft<span class="token punctuation">,</span>tup_botRight<span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">255</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> new_image<span class="token punctuation">,</span> rects

<span class="token keyword">def</span> <span class="token function">draw_parking</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> rects<span class="token punctuation">,</span> make_copy <span class="token operator">=</span> <span class="token boolean">True</span><span class="token punctuation">,</span> color<span class="token operator">=</span><span class="token punctuation">[</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> thickness<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">,</span> save <span class="token operator">=</span> <span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span> make_copy<span class="token punctuation">:</span>
        new_image <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
    gap <span class="token operator">=</span> <span class="token number">15.5</span>
    spot_dict <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span> <span class="token comment"># 字典:一个车位对应一个位置</span>
    tot_spots <span class="token operator">=</span> <span class="token number">0</span>
    <span class="token comment"># 微调</span>
    adj_y1 <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">:</span><span class="token number">28</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">:</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">:</span><span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">32</span><span class="token punctuation">}</span>
    adj_y2 <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span> <span class="token number">50</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">:</span><span class="token number">30</span><span class="token punctuation">}</span>
    
    adj_x1 <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token operator">-</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">}</span>
    adj_x2 <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span> <span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">}</span>
    <span class="token comment"># </span>
    <span class="token keyword">for</span> key <span class="token keyword">in</span> rects<span class="token punctuation">:</span>
        tup <span class="token operator">=</span> rects<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
        x1 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">+</span> adj_x1<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
        x2 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator">+</span> adj_x2<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
        y1 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">+</span> adj_y1<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
        y2 <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>tup<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">+</span> adj_y2<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
        cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span>x2<span class="token punctuation">,</span>y2<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">255</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span>
        <span class="token comment"># (y2-y1)//gap表示能停多少辆车</span>
        num_splits <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token builtin">abs</span><span class="token punctuation">(</span>y2<span class="token operator">-</span>y1<span class="token punctuation">)</span><span class="token operator">//</span>gap<span class="token punctuation">)</span>
        <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num_splits<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
            y <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1 <span class="token operator">+</span> i<span class="token operator">*</span>gap<span class="token punctuation">)</span>
            cv2<span class="token punctuation">.</span>line<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>x2<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> thickness<span class="token punctuation">)</span>
        <span class="token keyword">if</span> key <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">and</span> key <span class="token operator">&lt;</span> <span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token punctuation">:</span>        
            <span class="token comment">#竖直线</span>
            x <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x1 <span class="token operator">+</span> x2<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">2</span><span class="token punctuation">)</span>
            cv2<span class="token punctuation">.</span>line<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y2<span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> thickness<span class="token punctuation">)</span>
        <span class="token comment"># 计算数量</span>
        <span class="token keyword">if</span> key <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">or</span> key <span class="token operator">==</span> <span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
            tot_spots <span class="token operator">+=</span> num_splits <span class="token operator">+</span><span class="token number">1</span>
        <span class="token keyword">else</span><span class="token punctuation">:</span>
            tot_spots <span class="token operator">+=</span> <span class="token number">2</span><span class="token operator">*</span><span class="token punctuation">(</span>num_splits <span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span>  <span class="token comment"># 双排的乘2</span>
            
        <span class="token comment"># 字典对应好</span>
        <span class="token keyword">if</span> key <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">or</span> key <span class="token operator">==</span> <span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>rects<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
            <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num_splits<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
                cur_len <span class="token operator">=</span> <span class="token builtin">len</span><span class="token punctuation">(</span>spot_dict<span class="token punctuation">)</span>
                y <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1 <span class="token operator">+</span> i<span class="token operator">*</span>gap<span class="token punctuation">)</span>
                spot_dict<span class="token punctuation">[</span><span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y<span class="token operator">+</span>gap<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> cur_len <span class="token operator">+</span><span class="token number">1</span>        
        <span class="token keyword">else</span><span class="token punctuation">:</span>
            <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num_splits<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
                cur_len <span class="token operator">=</span> <span class="token builtin">len</span><span class="token punctuation">(</span>spot_dict<span class="token punctuation">)</span>
                y <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1 <span class="token operator">+</span> i<span class="token operator">*</span>gap<span class="token punctuation">)</span>
                x <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x1 <span class="token operator">+</span> x2<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">2</span><span class="token punctuation">)</span>
                spot_dict<span class="token punctuation">[</span><span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token operator">+</span>gap<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> cur_len <span class="token operator">+</span><span class="token number">1</span>
                spot_dict<span class="token punctuation">[</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y<span class="token operator">+</span>gap<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> cur_len <span class="token operator">+</span><span class="token number">2</span>   
    
    <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"total parking spaces: "</span><span class="token punctuation">,</span> tot_spots<span class="token punctuation">,</span> cur_len<span class="token punctuation">)</span>
    <span class="token keyword">if</span> save<span class="token punctuation">:</span>
        filename <span class="token operator">=</span> <span class="token string">'with_parking.jpg'</span>
        cv2<span class="token punctuation">.</span>imwrite<span class="token punctuation">(</span>filename<span class="token punctuation">,</span> new_image<span class="token punctuation">)</span>
    <span class="token keyword">return</span> new_image<span class="token punctuation">,</span> spot_dict

<span class="token keyword">def</span> <span class="token function">assign_spots_map</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> spot_dict<span class="token punctuation">,</span> make_copy <span class="token operator">=</span> <span class="token boolean">True</span><span class="token punctuation">,</span> color<span class="token operator">=</span><span class="token punctuation">[</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> thickness<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span> make_copy<span class="token punctuation">:</span>
        new_image <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
    <span class="token keyword">for</span> spot <span class="token keyword">in</span> spot_dict<span class="token punctuation">.</span>keys<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> spot
        cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x1<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token builtin">int</span><span class="token punctuation">(</span>y1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x2<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token builtin">int</span><span class="token punctuation">(</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> thickness<span class="token punctuation">)</span>
    <span class="token keyword">return</span> new_image

<span class="token keyword">def</span> <span class="token function">save_images_for_cnn</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> spot_dict<span class="token punctuation">,</span> folder_name <span class="token operator">=</span><span class="token string">'cnn_data'</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">for</span> spot <span class="token keyword">in</span> spot_dict<span class="token punctuation">.</span>keys<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> spot
        <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>x2<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token comment">#裁剪</span>
        spot_img <span class="token operator">=</span> image<span class="token punctuation">[</span>y1<span class="token punctuation">:</span>y2<span class="token punctuation">,</span> x1<span class="token punctuation">:</span>x2<span class="token punctuation">]</span>
        spot_img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>resize<span class="token punctuation">(</span>spot_img<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> fx<span class="token operator">=</span><span class="token number">2.0</span><span class="token punctuation">,</span> fy<span class="token operator">=</span><span class="token number">2.0</span><span class="token punctuation">)</span> 
        spot_id <span class="token operator">=</span> spot_dict<span class="token punctuation">[</span>spot<span class="token punctuation">]</span>
        
        filename <span class="token operator">=</span> <span class="token string">'spot'</span> <span class="token operator">+</span> <span class="token builtin">str</span><span class="token punctuation">(</span>spot_id<span class="token punctuation">)</span> <span class="token operator">+</span><span class="token string">'.jpg'</span>
        <span class="token keyword">print</span><span class="token punctuation">(</span>spot_img<span class="token punctuation">.</span>shape<span class="token punctuation">,</span> filename<span class="token punctuation">,</span> <span class="token punctuation">(</span>x1<span class="token punctuation">,</span>x2<span class="token punctuation">,</span>y1<span class="token punctuation">,</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
        
        cv2<span class="token punctuation">.</span>imwrite<span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>folder_name<span class="token punctuation">,</span> filename<span class="token punctuation">)</span><span class="token punctuation">,</span> spot_img<span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">make_prediction</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span>model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token comment">#预处理</span>
    img <span class="token operator">=</span> image<span class="token operator">/</span><span class="token number">255</span><span class="token punctuation">.</span>

    <span class="token comment">#转换成4D tensor</span>
    image <span class="token operator">=</span> np<span class="token punctuation">.</span>expand_dims<span class="token punctuation">(</span>img<span class="token punctuation">,</span> axis<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">)</span>

    <span class="token comment"># 用训练好的模型进行训练</span>
    class_predicted <span class="token operator">=</span> model<span class="token punctuation">.</span>predict<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
    inID <span class="token operator">=</span> np<span class="token punctuation">.</span>argmax<span class="token punctuation">(</span>class_predicted<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
    label <span class="token operator">=</span> class_dictionary<span class="token punctuation">[</span>inID<span class="token punctuation">]</span>
    <span class="token keyword">return</span> label
<span class="token keyword">def</span> <span class="token function">predict_on_image</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>image<span class="token punctuation">,</span> spot_dict <span class="token punctuation">,</span> model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">,</span>make_copy<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> color <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> alpha<span class="token operator">=</span><span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span> make_copy<span class="token punctuation">:</span>
        new_image <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
        overlay <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'new_image'</span><span class="token punctuation">,</span>new_image<span class="token punctuation">)</span>
    cnt_empty <span class="token operator">=</span> <span class="token number">0</span>
    all_spots <span class="token operator">=</span> <span class="token number">0</span>
    <span class="token keyword">for</span> spot <span class="token keyword">in</span> spot_dict<span class="token punctuation">.</span>keys<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        all_spots <span class="token operator">+=</span> <span class="token number">1</span>
        <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> spot
        <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>x2<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
        spot_img <span class="token operator">=</span> image<span class="token punctuation">[</span>y1<span class="token punctuation">:</span>y2<span class="token punctuation">,</span> x1<span class="token punctuation">:</span>x2<span class="token punctuation">]</span>
        spot_img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>resize<span class="token punctuation">(</span>spot_img<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">48</span><span class="token punctuation">,</span> <span class="token number">48</span><span class="token punctuation">)</span><span class="token punctuation">)</span> 
        
        label <span class="token operator">=</span> self<span class="token punctuation">.</span>make_prediction<span class="token punctuation">(</span>spot_img<span class="token punctuation">,</span>model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">)</span>
        <span class="token keyword">if</span> label <span class="token operator">==</span> <span class="token string">'empty'</span><span class="token punctuation">:</span>
            cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>overlay<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x1<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token builtin">int</span><span class="token punctuation">(</span>y1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x2<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token builtin">int</span><span class="token punctuation">(</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
            cnt_empty <span class="token operator">+=</span> <span class="token number">1</span>
            
    cv2<span class="token punctuation">.</span>addWeighted<span class="token punctuation">(</span>overlay<span class="token punctuation">,</span> alpha<span class="token punctuation">,</span> new_image<span class="token punctuation">,</span> <span class="token number">1</span> <span class="token operator">-</span> alpha<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> new_image<span class="token punctuation">)</span>
            
    cv2<span class="token punctuation">.</span>putText<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token string">"Available: %d spots"</span> <span class="token operator">%</span>cnt_empty<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">95</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    cv2<span class="token punctuation">.</span>FONT_HERSHEY_SIMPLEX<span class="token punctuation">,</span>
    <span class="token number">0.7</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span>
    
    cv2<span class="token punctuation">.</span>putText<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token string">"Total: %d spots"</span> <span class="token operator">%</span>all_spots<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">125</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    cv2<span class="token punctuation">.</span>FONT_HERSHEY_SIMPLEX<span class="token punctuation">,</span>
    <span class="token number">0.7</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span>
    save <span class="token operator">=</span> <span class="token boolean">False</span>
    
    <span class="token keyword">if</span> save<span class="token punctuation">:</span>
        filename <span class="token operator">=</span> <span class="token string">'with_marking.jpg'</span>
        cv2<span class="token punctuation">.</span>imwrite<span class="token punctuation">(</span>filename<span class="token punctuation">,</span> new_image<span class="token punctuation">)</span>
    self<span class="token punctuation">.</span>cv_show<span class="token punctuation">(</span><span class="token string">'new_image'</span><span class="token punctuation">,</span>new_image<span class="token punctuation">)</span>
    
    <span class="token keyword">return</span> new_image
    
<span class="token keyword">def</span> <span class="token function">predict_on_video</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>video_name<span class="token punctuation">,</span>final_spot_dict<span class="token punctuation">,</span> model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">,</span>ret<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">:</span>   
    cap <span class="token operator">=</span> cv2<span class="token punctuation">.</span>VideoCapture<span class="token punctuation">(</span>video_name<span class="token punctuation">)</span>
    count <span class="token operator">=</span> <span class="token number">0</span>
    <span class="token keyword">while</span> ret<span class="token punctuation">:</span>
        ret<span class="token punctuation">,</span> image <span class="token operator">=</span> cap<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span>
        count <span class="token operator">+=</span> <span class="token number">1</span>
        <span class="token keyword">if</span> count <span class="token operator">==</span> <span class="token number">5</span><span class="token punctuation">:</span>
            count <span class="token operator">=</span> <span class="token number">0</span>
            
            new_image <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
            overlay <span class="token operator">=</span> np<span class="token punctuation">.</span>copy<span class="token punctuation">(</span>image<span class="token punctuation">)</span>
            cnt_empty <span class="token operator">=</span> <span class="token number">0</span>
            all_spots <span class="token operator">=</span> <span class="token number">0</span>
            color <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span> 
            alpha<span class="token operator">=</span><span class="token number">0.5</span>
            <span class="token keyword">for</span> spot <span class="token keyword">in</span> final_spot_dict<span class="token punctuation">.</span>keys<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
                all_spots <span class="token operator">+=</span> <span class="token number">1</span>
                <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> spot
                <span class="token punctuation">(</span>x1<span class="token punctuation">,</span> y1<span class="token punctuation">,</span> x2<span class="token punctuation">,</span> y2<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>x2<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span>
                spot_img <span class="token operator">=</span> image<span class="token punctuation">[</span>y1<span class="token punctuation">:</span>y2<span class="token punctuation">,</span> x1<span class="token punctuation">:</span>x2<span class="token punctuation">]</span>
                spot_img <span class="token operator">=</span> cv2<span class="token punctuation">.</span>resize<span class="token punctuation">(</span>spot_img<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">48</span><span class="token punctuation">,</span><span class="token number">48</span><span class="token punctuation">)</span><span class="token punctuation">)</span> 

                label <span class="token operator">=</span> self<span class="token punctuation">.</span>make_prediction<span class="token punctuation">(</span>spot_img<span class="token punctuation">,</span>model<span class="token punctuation">,</span>class_dictionary<span class="token punctuation">)</span>
                <span class="token keyword">if</span> label <span class="token operator">==</span> <span class="token string">'empty'</span><span class="token punctuation">:</span>
                    cv2<span class="token punctuation">.</span>rectangle<span class="token punctuation">(</span>overlay<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x1<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token builtin">int</span><span class="token punctuation">(</span>y1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>x2<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token builtin">int</span><span class="token punctuation">(</span>y2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> color<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
                    cnt_empty <span class="token operator">+=</span> <span class="token number">1</span>

            cv2<span class="token punctuation">.</span>addWeighted<span class="token punctuation">(</span>overlay<span class="token punctuation">,</span> alpha<span class="token punctuation">,</span> new_image<span class="token punctuation">,</span> <span class="token number">1</span> <span class="token operator">-</span> alpha<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> new_image<span class="token punctuation">)</span>

            cv2<span class="token punctuation">.</span>putText<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token string">"Available: %d spots"</span> <span class="token operator">%</span>cnt_empty<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">95</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            cv2<span class="token punctuation">.</span>FONT_HERSHEY_SIMPLEX<span class="token punctuation">,</span>
            <span class="token number">0.7</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span>

            cv2<span class="token punctuation">.</span>putText<span class="token punctuation">(</span>new_image<span class="token punctuation">,</span> <span class="token string">"Total: %d spots"</span> <span class="token operator">%</span>all_spots<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">125</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            cv2<span class="token punctuation">.</span>FONT_HERSHEY_SIMPLEX<span class="token punctuation">,</span>
            <span class="token number">0.7</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span>
            cv2<span class="token punctuation">.</span>imshow<span class="token punctuation">(</span><span class="token string">'frame'</span><span class="token punctuation">,</span> new_image<span class="token punctuation">)</span>
            <span class="token keyword">if</span> cv2<span class="token punctuation">.</span>waitKey<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xFF</span> <span class="token operator">==</span> <span class="token builtin">ord</span><span class="token punctuation">(</span><span class="token string">'q'</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
                <span class="token keyword">break</span>

    cv2<span class="token punctuation">.</span>destroyAllWindows<span class="token punctuation">(</span><span class="token punctuation">)</span>
    cap<span class="token punctuation">.</span>release<span class="token punctuation">(</span><span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 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
  • 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
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318

train.py

import numpy
import os
from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential, Model
from keras.layers import Dropout, Flatten, Dense, GlobalAveragePooling2D
from keras import backend as k
from keras.callbacks import ModelCheckpoint, LearningRateScheduler, TensorBoard, EarlyStopping
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.initializers import TruncatedNormal
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense

files_train = 0
files_validation = 0

cwd = os.getcwd()
folder = ‘train_data/train’
for sub_folder in os.listdir(folder):
path, dirs, files = next(os.walk(os.path.join(folder,sub_folder)))
files_train += len(files)

folder = ‘train_data/test’
for sub_folder in os.listdir(folder):
path, dirs, files = next(os.walk(os.path.join(folder,sub_folder)))
files_validation += len(files)

print(files_train,files_validation)

img_width, img_height = 48, 48
train_data_dir = “train_data/train”
validation_data_dir = “train_data/test”
nb_train_samples = files_train
nb_validation_samples = files_validation
batch_size = 32
epochs = 15
num_classes = 2

model = applications.VGG16(weights=‘imagenet’, include_top=False, input_shape = (img_width, img_height, 3))

for layer in model.layers[:10]:
layer.trainable = False

x = model.output
x = Flatten()(x)
predictions = Dense(num_classes, activation=“softmax”)(x)

model_final = Model(input = model.input, output = predictions)

model_final.compile(loss = “categorical_crossentropy”,
optimizer = optimizers.SGD(lr=0.0001, momentum=0.9),
metrics=[“accuracy”])

train_datagen = ImageDataGenerator(
rescale = 1./255,
horizontal_flip = True,
fill_mode = “nearest”,
zoom_range = 0.1,
width_shift_range = 0.1,
height_shift_range=0.1,
rotation_range=5)

test_datagen = ImageDataGenerator(
rescale = 1./255,
horizontal_flip = True,
fill_mode = “nearest”,
zoom_range = 0.1,
width_shift_range = 0.1,
height_shift_range=0.1,
rotation_range=5)

train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = “categorical”)

validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size = (img_height, img_width),
class_mode = “categorical”)

checkpoint = ModelCheckpoint(“car1.h5”, monitor=‘val_acc’, verbose=1, save_best_only=True, save_weights_only=False, mode=‘auto’, period=1)
early = EarlyStopping(monitor=‘val_acc’, min_delta=0, patience=10, verbose=1, mode=‘auto’)

history_object = model_final.fit_generator(
train_generator,
samples_per_epoch = nb_train_samples,
epochs = epochs,
validation_data = validation_generator,
nb_val_samples = nb_validation_samples,
callbacks = [checkpoint, early])

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 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
  • 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
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

完整代码就这些
h5文件和原图等其他课件的链接:https://pan.baidu.com/s/1oYpshb-RY-2g8lAM9sf3Jg 提取码:qics

代码没问题,但我手头的这个h5文件貌似有些异常,有兴趣的同学可以再训练一个

以上来自B站唐老师的讲解视频

结束语

个人感受】:代码是仅限于这类型的停车场图片,预处理部分已经算很大部分是手工的了,所以这不像深度学习的网络框架那样 易搬运。故,我们要学习的是遇到这种类似的情况,要进行哪些预处理,才能获得我们要的结果(比如,停车场的形状不规则的时候,可以手工指定重要的边界点和角点,进行截取;阈值的设定;直线的获取等等)。然后再结合深度学习的分类任务进行识别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值