你如何用Python计算OpenCV中的汽车?

nic*_*ine 12 python opencv image-processing

我正在尝试使用OpenCV和Python自动计算图像中的汽车数量.

在此输入图像描述

最初我认为我可以通过一些细分来做到这一点,但我没有取得多大成功.然后我认为霍夫变换可能有助于计算汽车周围的边界,但它只是真正选择了停车位线.我唯一能想到的就是开始训练一些关于汽车和非汽车模板的比赛,但我希望有更简单的东西在这里做得很好.我也试过边缘检测看起来很积极但不确定如何继续:

在此输入图像描述

and*_*rew 5

好吧,所以......我可能在这方面做了太多工作,但看起来很简单.

对于我的实施,我决定最好找到空的停车位,并假设所有其他空间都被占用.为了确定一个地点是否为空,我只是将它与道路的停车位大小部分进行比较.这意味着相同的算法应该工作无论是亮还是暗等,因为模板是直接从图像中提取的.

此时我只是进行模板匹配(我尝试了各种方法,但cv2.TM_CCORR_NORMED效果最好).这给出了一个不错的结果,现在我们需要处理它.

在此输入图像描述

我在停车场行周围创建了ROI(感兴趣的区域).然后我通过每列统计数据将它们折叠为单个向量.我看一下这个意思. 在此输入图像描述

它是一个非常好的指标,你已经可以清楚地看到空白的位置.但深色车仍然存在一些问题,所以现在我们决定看另一个统计数据,方差怎么样?停车场在整个地区都非常稳定.另一方面,汽车有一些变化,窗户,屋顶镜子有一些变化.所以我绘制了"倒置"方差.因此,方差为0时,不是没有变化,而是方差为1.它看起来像这样 在此输入图像描述

这看起来很有前途!但你知道什么更好吗?结合这两个!所以让我们将它们相乘,我将这个结果称为"概率",因为它应该在0和1之间 在此输入图像描述

现在你可以真正看到空白区域和黑暗车厢之间的区别.所以我们做一些简单的门槛.这很棒,但它没有给你NUMBER个车辆/空位.此时,我们逐列检查"概率"列,我们在阈值上查找一定数量的连续像素.多少像素?与汽车一样多的像素很宽.这种"滞后"型模型应该抑制任何峰值或伪数据点.

现在这一切都汇集在一起​​,我们假设空间的数量是恒定的(我认为是合理的假设),我们只是说number of cars = number of spaces - number of empty spaces并标记图像

在此输入图像描述

并打印一些结果

found 24 cars and 1 empty space(s) in row 1
found 23 cars and 0 empty space(s) in row 2
found 20 cars and 3 empty space(s) in row 3
found 22 cars and 0 empty space(s) in row 4
found 13 cars and 9 empty space(s) in row 5
Run Code Online (Sandbox Code Playgroud)

当然还有代码.它可能不是最有效的,但我通常是一个matlab人,它是我的第一个openCV/Python项目

import cv2
import numpy as np
from matplotlib import pyplot as plt

# this just keeps things neat
class ParkingLotRow(object):
    top_left=None
    bot_right=None
    roi=None
    col_mean=None
    inverted_variance=None
    empty_col_probability=None
    empty_spaces=0
    total_spaces=None

    def __init__(self,top_left,bot_right,num_spaces):
        self.top_left = top_left
        self.bot_right = bot_right
        self.total_spaces = num_spaces

############################ BEGIN: TWEAKING PARAMETERS ###########################################
car_width = 8       #in pixels
thresh = 0.975      #used to determine if a spot is empty
############################### END: TWEAKING PARAMETERS ###########################################
parking_rows = []

# defines regions of interest, row 1 is on top, row 5 is on bottom, values determined empirically
parking_rows.append(ParkingLotRow((  1, 20),(496, 41),25))     #row 1
parking_rows.append(ParkingLotRow((  1, 87),(462,105),23))     #row 2
parking_rows.append(ParkingLotRow((  1,140),(462,158),23))     #row 3
parking_rows.append(ParkingLotRow((  1,222),(462,240),22))     #row 4
parking_rows.append(ParkingLotRow((  1,286),(462,304),22))     #row 5

#read image
img = cv2.imread('parking_lot.jpg')
img2 = img.copy()

#creates a template, its jsut a car sized patch of pavement
template = img[138:165,484:495]
m, n, chan = img.shape

#blurs the template a bit
template = cv2.GaussianBlur(template,(3,3),2)
h, w, chan = template.shape

# Apply template Matching 
res = cv2.matchTemplate(img,template,cv2.TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
#adds bounding box around template
cv2.rectangle(img,top_left, bottom_right, 255, 5)

#adds bounding box on ROIs
for curr_parking_lot_row in parking_rows:
    tl = curr_parking_lot_row.top_left
    br = curr_parking_lot_row.bot_right

    cv2.rectangle(res,tl, br, 1, 5)

#displays some intermediate results
plt.subplot(121),plt.imshow(res,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
plt.title('Original, template in blue'), plt.xticks([]), plt.yticks([])

plt.show()

curr_idx = int(0)

#overlay on original picture
f0 = plt.figure(4)
plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)),plt.title('Original')


for curr_parking_lot_row in parking_rows:
    #creates the region of interest
    tl = curr_parking_lot_row.top_left
    br = curr_parking_lot_row.bot_right

    my_roi = res[tl[1]:br[1],tl[0]:br[0]]

    #extracts statistics by column
    curr_parking_lot_row.col_mean = np.mean(my_roi, 0)
    curr_parking_lot_row.inverted_variance = 1 - np.var(my_roi,0)
    curr_parking_lot_row.empty_col_probability = curr_parking_lot_row.col_mean * curr_parking_lot_row.inverted_variance

    #creates some plots
    f1 = plt.figure(1)
    plt.subplot('51%d' % (curr_idx + 1)),plt.plot(curr_parking_lot_row.col_mean),plt.title('Row %d correlation' %(curr_idx + 1))

    f2 = plt.figure(2)
    plt.subplot('51%d' % (curr_idx + 1)),plt.plot(curr_parking_lot_row.inverted_variance),plt.title('Row %d variance' %(curr_idx + 1))

    f3 = plt.figure(3)
    plt.subplot('51%d' % (curr_idx + 1))
    plt.plot(curr_parking_lot_row.empty_col_probability),plt.title('Row %d empty probability ' %(curr_idx + 1))
    plt.plot((1,n),(thresh,thresh),c='r')

    #counts empty spaces
    num_consec_pixels_over_thresh = 0
    curr_col = 0

    for prob_val in curr_parking_lot_row.empty_col_probability:
        curr_col += 1

        if(prob_val > thresh):
            num_consec_pixels_over_thresh += 1
        else:
            num_consec_pixels_over_thresh = 0

        if (num_consec_pixels_over_thresh >= car_width):
            curr_parking_lot_row.empty_spaces += 1

            #adds mark to plt
            plt.figure(3)   # the probability graph
            plt.scatter(curr_col,1,c='g')

            plt.figure(4)   #parking lot image
            plt.scatter(curr_col,curr_parking_lot_row.top_left[1] + 7, c='g')

            #to prevent doubel counting cars, just reset the counter
            num_consec_pixels_over_thresh = 0

    #sets axis range, apparantlly they mess up when adding the scatters
    plt.figure(3)
    plt.xlim([0,n])

    #print out some stats
    print('found {0} cars and {1} empty space(s) in row {2}'.format(
        curr_parking_lot_row.total_spaces - curr_parking_lot_row.empty_spaces,
        curr_parking_lot_row.empty_spaces,
        curr_idx +1))

    curr_idx += 1

#plot some figures
plt.show()
Run Code Online (Sandbox Code Playgroud)


ABC*_*ABC 1

快速的 matlab 代码,可以轻松转换为 python,帮助您入门...

b = rgb2hsv(I);
se = strel('rectangle', [2,4]); %# structuring element
BW = b(:,:,3)>0.5; 
BW2 = bwareaopen(BW,30);
BW3 = imerode(BW2, se); 
BW4 = imdilate(BW3, se);
CC = bwconncomp(BW4);
Run Code Online (Sandbox Code Playgroud)

从这里您知道需要查看 CC 的放置结果并计算宽高比,因为您大约知道汽车有多大。这是我的 BW4 输出结果。

在此输入图像描述