使用OpenCV实现道路车辆计数的使用方法

今天,我们将一起探讨如何基于计算机视觉实现道路交通计数。

在本教程中,我们将仅使用Python和OpenCV,并借助背景减除算法非常简单地进行运动检测。

我们将从以下四个方面进行介绍:

1. 用于物体检测的背景减法算法主要思想。

2. OpenCV图像过滤器。

3. 利用轮廓检测物体。

4. 建立进一步数据处理的结构。

背景扣除算法

有许多不同的背景扣除算法,但是它们的主要思想都很简单。

假设有一个房间的视频,在某些帧上没有人和宠物,那么此时的视频基本为静态的,我们将其称为背景(background_layer)。因此要获取在视频上移动的对象,我们只需要:用当前帧减去背景即可。

由于光照变化,人为移动物体,或者始终存在移动的人和宠物,我们将无法获得静态帧。在这种情况下,我们从视频中选出一些图像帧,如果绝大多数图像帧中都具有某个相同的像素点,则此将像素作为background_layer中的一部分。

我们将使用MOG算法进行背景扣除

原始帧

代码如下所示:

import os
import logging
import logging.handlers
import random

import numpy as np
import skvideo.io
import cv2
import matplotlib.pyplot as plt

import utils
# without this some strange errors happen
cv2.ocl.setUseOpenCL(False)
random.seed(123)

# ============================================================================
IMAGE_DIR = "./out"
VIDEO_SOURCE = "input.mp4"
SHAPE = (720, 1280) # HxW
# ============================================================================

def train_bg_subtractor(inst, cap, num=500):
  '''
    BG substractor need process some amount of frames to start giving result
  '''
  print ('Training BG Subtractor...')
  i = 0
  for frame in cap:
    inst.apply(frame, None, 0.001)
    i += 1
    if i >= num:
      return cap

def main():
  log = logging.getLogger("main")

  # creting MOG bg subtractor with 500 frames in cache
  # and shadow detction
  bg_subtractor = cv2.createBackgroundSubtractorMOG2(
    history=500, detectShadows=True)

  # Set up image source
  # You can use also CV2, for some reason it not working for me
  cap = skvideo.io.vreader(VIDEO_SOURCE)

  # skipping 500 frames to train bg subtractor
  train_bg_subtractor(bg_subtractor, cap, num=500)

  frame_number = -1
  for frame in cap:
    if not frame.any():
      log.error("Frame capture failed, stopping...")
      break

    frame_number += 1
    utils.save_frame(frame, "./out/frame_%04d.png" % frame_number)
    fg_mask = bg_subtractor.apply(frame, None, 0.001)
    utils.save_frame(frame, "./out/fg_mask_%04d.png" % frame_number)
# ============================================================================

if __name__ == "__main__":
  log = utils.init_logging()

  if not os.path.exists(IMAGE_DIR):
    log.debug("Creating image directory `%s`...", IMAGE_DIR)
    os.makedirs(IMAGE_DIR)

  main()

处理后得到下面的前景图像

去除背景后的前景图像

我们可以看出前景图像上有一些噪音,可以通过标准滤波技术可以将其消除。

滤波

针对我们现在的情况,我们将需要以下滤波函数:Threshold、Erode、Dilate、Opening、Closing。

首先,我们使用“Closing”来移除区域中的间隙,然后使用“Opening”来移除个别独立的像素点,然后使用“Dilate”进行扩张以使对象变粗。代码如下:

def filter_mask(img):
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
  # Fill any small holes
  closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
  # Remove noise
  opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel)
  # Dilate to merge adjacent blobs
  dilation = cv2.dilate(opening, kernel, iterations=2)
  # threshold
  th = dilation[dilation < 240] = 0
  return th

处理后的前景如下:

利用轮廓进行物体检测

我们将使用cv2.findContours函数对轮廓进行检测。我们在使用的时候可以选择的参数为:

cv2.CV_RETR_EXTERNAL------仅获取外部轮廓。

cv2.CV_CHAIN_APPROX_TC89_L1------使用Teh-Chin链逼近算法(更快)

代码如下:

def get_centroid(x, y, w, h):
   x1 = int(w / 2)
   y1 = int(h / 2)
   cx = x + x1
   cy = y + y1
   return (cx, cy)

 def detect_vehicles(fg_mask, min_contour_width=35, min_contour_height=35):
   matches = []
   # finding external contours
   im, contours, hierarchy = cv2.findContours(
     fg_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
   # filtering by with, height
   for (i, contour) in enumerate(contours):
     (x, y, w, h) = cv2.boundingRect(contour)
     contour_valid = (w >= min_contour_width) and (
       h >= min_contour_height)
     if not contour_valid:
       continue
     # getting center of the bounding box
     centroid = get_centroid(x, y, w, h)
     matches.append(((x, y, w, h), centroid))
   return matches

建立数据处理框架

我们都知道在ML和CV中,没有一个算法可以处理所有问题。即使存在这种算法,我们也不会使用它,因为它很难大规模有效。例如几年前Netflix公司用300万美元的奖金悬赏最佳电影推荐算法。有一个团队完成这个任务,但是他们的推荐算法无法大规模运行,因此其实对公司毫无用处。但是,Netflix公司仍奖励了他们100万美元。

接下来我们来建立解决当前问题的框架,这样可以使数据的处理更加方便

class PipelineRunner(object):
   '''
     Very simple pipline.
     Just run passed processors in order with passing context from one to
     another.
     You can also set log level for processors.
   '''
   def __init__(self, pipeline=None, log_level=logging.DEBUG):
     self.pipeline = pipeline or []
     self.context = {}
     self.log = logging.getLogger(self.__class__.__name__)
     self.log.setLevel(log_level)
     self.log_level = log_level
     self.set_log_level()
   def set_context(self, data):
     self.context = data
   def add(self, processor):
     if not isinstance(processor, PipelineProcessor):
       raise Exception(
         'Processor should be an isinstance of PipelineProcessor.')
     processor.log.setLevel(self.log_level)
     self.pipeline.append(processor)

   def remove(self, name):
     for i, p in enumerate(self.pipeline):
       if p.__class__.__name__ == name:
         del self.pipeline[i]
         return True
     return False

   def set_log_level(self):
     for p in self.pipeline:
       p.log.setLevel(self.log_level)

   def run(self):
     for p in self.pipeline:
       self.context = p(self.context)
     self.log.debug("Frame #%d processed.", self.context['frame_number'])
     return self.context

 class PipelineProcessor(object):
   '''
     Base class for processors.
   '''
   def __init__(self):
     self.log = logging.getLogger(self.__class__.__name__)

首先我们获取一张处理器运行顺序的列表,让每个处理器完成一部分工作,在案顺序完成执行以获得最终结果。

我们首先创建轮廓检测处理器。轮廓检测处理器只需将前面的背景扣除,滤波和轮廓检测部分合并在一起即可,代码如下所示:

class ContourDetection(PipelineProcessor):
   '''
     Detecting moving objects.
     Purpose of this processor is to subtrac background, get moving objects
     and detect them with a cv2.findContours method, and then filter off-by
     width and height.
     bg_subtractor - background subtractor isinstance.
     min_contour_width - min bounding rectangle width.
     min_contour_height - min bounding rectangle height.
     save_image - if True will save detected objects mask to file.
     image_dir - where to save images(must exist).
   '''

   def __init__(self, bg_subtractor, min_contour_width=35, min_contour_height=35, save_image=False, image_dir='images'):
     super(ContourDetection, self).__init__()
     self.bg_subtractor = bg_subtractor
     self.min_contour_width = min_contour_width
     self.min_contour_height = min_contour_height
     self.save_image = save_image
     self.image_dir = image_dir

   def filter_mask(self, img, a=None):
     '''
       This filters are hand-picked just based on visual tests
     '''
     kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
     # Fill any small holes
     closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
     # Remove noise
     opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel)
     # Dilate to merge adjacent blobs
     dilation = cv2.dilate(opening, kernel, iterations=2)
     return dilation

   def detect_vehicles(self, fg_mask, context):
     matches = []
     # finding external contours
     im2, contours, hierarchy = cv2.findContours(
       fg_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
     for (i, contour) in enumerate(contours):
       (x, y, w, h) = cv2.boundingRect(contour)
       contour_valid = (w >= self.min_contour_width) and (
         h >= self.min_contour_height)
       if not contour_valid:
         continue
       centroid = utils.get_centroid(x, y, w, h)
       matches.append(((x, y, w, h), centroid))
     return matches

   def __call__(self, context):
     frame = context['frame'].copy()
     frame_number = context['frame_number']
     fg_mask = self.bg_subtractor.apply(frame, None, 0.001)
     # just thresholding values
     fg_mask[fg_mask < 240] = 0
     fg_mask = self.filter_mask(fg_mask, frame_number)
     if self.save_image:
       utils.save_frame(fg_mask, self.image_dir +
                "/mask_%04d.png" % frame_number, flip=False)
     context['objects'] = self.detect_vehicles(fg_mask, context)
     context['fg_mask'] = fg_mask
     return contex

现在,让我们创建一个处理器,该处理器将找出不同的帧上检测到的相同对象,创建路径,并对到达出口区域的车辆进行计数。代码如下所示:

  '''
    Counting vehicles that entered in exit zone.

    Purpose of this class based on detected object and local cache create
    objects pathes and count that entered in exit zone defined by exit masks.

    exit_masks - list of the exit masks.
    path_size - max number of points in a path.
    max_dst - max distance between two points.
  '''

  def __init__(self, exit_masks=[], path_size=10, max_dst=30, x_weight=1.0, y_weight=1.0):
    super(VehicleCounter, self).__init__()

    self.exit_masks = exit_masks

    self.vehicle_count = 0
    self.path_size = path_size
    self.pathes = []
    self.max_dst = max_dst
    self.x_weight = x_weight
    self.y_weight = y_weight

  def check_exit(self, point):
    for exit_mask in self.exit_masks:
      try:
        if exit_mask[point[1]][point[0]] == 255:
          return True
      except:
        return True
    return False

  def __call__(self, context):
    objects = context['objects']
    context['exit_masks'] = self.exit_masks
    context['pathes'] = self.pathes
    context['vehicle_count'] = self.vehicle_count
    if not objects:
      return context

    points = np.array(objects)[:, 0:2]
    points = points.tolist()

    # add new points if pathes is empty
    if not self.pathes:
      for match in points:
        self.pathes.append([match])

    else:
      # link new points with old pathes based on minimum distance between
      # points
      new_pathes = []

      for path in self.pathes:
        _min = 999999
        _match = None
        for p in points:
          if len(path) == 1:
            # distance from last point to current
            d = utils.distance(p[0], path[-1][0])
          else:
            # based on 2 prev points predict next point and calculate
            # distance from predicted next point to current
            xn = 2 * path[-1][0][0] - path[-2][0][0]
            yn = 2 * path[-1][0][1] - path[-2][0][1]
            d = utils.distance(
              p[0], (xn, yn),
              x_weight=self.x_weight,
              y_weight=self.y_weight
            )

          if d < _min:
            _min = d
            _match = p

        if _match and _min <= self.max_dst:
          points.remove(_match)
          path.append(_match)
          new_pathes.append(path)

        # do not drop path if current frame has no matches
        if _match is None:
          new_pathes.append(path)

      self.pathes = new_pathes

      # add new pathes
      if len(points):
        for p in points:
          # do not add points that already should be counted
          if self.check_exit(p[1]):
            continue
          self.pathes.append([p])

    # save only last N points in path
    for i, _ in enumerate(self.pathes):
      self.pathes[i] = self.pathes[i][self.path_size * -1:]

    # count vehicles and drop counted pathes:
    new_pathes = []
    for i, path in enumerate(self.pathes):
      d = path[-2:]

      if (
        # need at list two points to count
        len(d) >= 2 and
        # prev point not in exit zone
        not self.check_exit(d[0][1]) and
        # current point in exit zone
        self.check_exit(d[1][1]) and
        # path len is bigger then min
        self.path_size <= len(path)
      ):
        self.vehicle_count += 1
      else:
        # prevent linking with path that already in exit zone
        add = True
        for p in path:
          if self.check_exit(p[1]):
            add = False
            break
        if add:
          new_pathes.append(path)

    self.pathes = new_pathes

    context['pathes'] = self.pathes
    context['objects'] = objects
    context['vehicle_count'] = self.vehicle_count

    self.log.debug('#VEHICLES FOUND: %s' % self.vehicle_count)

    return context

上面的代码有点复杂,因此让我们一个部分一个部分的介绍一下。

上面的图像中绿色的部分是出口区域。我们在这里对车辆进行计数,只有当车辆移动的长度超过3个点我们才进行计算

我们使用掩码来解决这个问题,因为它比使用矢量算法有效且简单得多。只需使用“二进制和”即可选出车辆区域中点。设置方式如下:

EXIT_PTS = np.array([
   [[732, 720], [732, 590], [1280, 500], [1280, 720]],
   [[0, 400], [645, 400], [645, 0], [0, 0]]
 ])

 base = np.zeros(SHAPE + (3,), dtype='uint8')
 exit_mask = cv2.fillPoly(base, EXIT_PTS, (255, 255, 255))[:, :, 0]

现在我们将检测到的点链接起来。

对于第一帧图像,我们将所有点均添加为新路径。

接下来,如果len(path)== 1,我们在新检测到的对象中找到与每条路径最后一点距离最近的对象。

如果len(path)> 1,则使用路径中的最后两个点,即在同一条线上预测新点,并找到该点与当前点之间的最小距离。

具有最小距离的点将添加到当前路径的末端并从列表中删除。如果在此之后还剩下一些点,我们会将其添加为新路径。这个过程中我们还会限制路径中的点数。

new_pathes = []
 for path in self.pathes:
   _min = 999999
   _match = None
   for p in points:
     if len(path) == 1:
       # distance from last point to current
       d = utils.distance(p[0], path[-1][0])
     else:
       # based on 2 prev points predict next point and calculate
       # distance from predicted next point to current
       xn = 2 * path[-1][0][0] - path[-2][0][0]
       yn = 2 * path[-1][0][1] - path[-2][0][1]
       d = utils.distance(
         p[0], (xn, yn),
         x_weight=self.x_weight,
         y_weight=self.y_weight
       )

     if d < _min:
       _min = d
       _match = p

   if _match and _min <= self.max_dst:
     points.remove(_match)
     path.append(_match)
     new_pathes.append(path)

   # do not drop path if current frame has no matches
   if _match is None:
     new_pathes.append(path)

 self.pathes = new_pathes

 # add new pathes
 if len(points):
   for p in points:
     # do not add points that already should be counted
     if self.check_exit(p[1]):
       continue
     self.pathes.append([p])

 # save only last N points in path
 for i, _ in enumerate(self.pathes):
   self.pathes[i] = self.pathes[i][self.path_size * -1:]

现在,我们将尝试计算进入出口区域的车辆。为此,我们需获取路径中的最后2个点,并检查len(path)是否应大于限制。

# count vehicles and drop counted pathes:
  new_pathes = []
  for i, path in enumerate(self.pathes):
    d = path[-2:]
    if (
      # need at list two points to count
      len(d) >= 2 and
      # prev point not in exit zone
      not self.check_exit(d[0][1]) and
      # current point in exit zone
      self.check_exit(d[1][1]) and
      # path len is bigger then min
      self.path_size <= len(path)
    ):
      self.vehicle_count += 1
    else:
      # prevent linking with path that already in exit zone
      add = True
      for p in path:
        if self.check_exit(p[1]):
          add = False
          break
      if add:
        new_pathes.append(path)
  self.pathes = new_pathes

  context['pathes'] = self.pathes
  context['objects'] = objects
  context['vehicle_count'] = self.vehicle_count
  self.log.debug('#VEHICLES FOUND: %s' % self.vehicle_count)
  return context

最后两个处理器是CSV编写器,用于创建报告CSV文件,以及用于调试和精美图片的可视化。

class CsvWriter(PipelineProcessor):
    def __init__(self, path, name, start_time=0, fps=15):
      super(CsvWriter, self).__init__()
      self.fp = open(os.path.join(path, name), 'w')
      self.writer = csv.DictWriter(self.fp, fieldnames=['time', 'vehicles'])
      self.writer.writeheader()
      self.start_time = start_time
      self.fps = fps
      self.path = path
      self.name = name
      self.prev = None
    def __call__(self, context):
      frame_number = context['frame_number']
      count = _count = context['vehicle_count']
      if self.prev:
        _count = count - self.prev
      time = ((self.start_time + int(frame_number / self.fps)) * 100
          + int(100.0 / self.fps) * (frame_number % self.fps))
      self.writer.writerow({'time': time, 'vehicles': _count})
      self.prev = count
      return context
  class Visualizer(PipelineProcessor):
    def __init__(self, save_image=True, image_dir='images'):
      super(Visualizer, self).__init__()
      self.save_image = save_image
      self.image_dir = image_dir
    def check_exit(self, point, exit_masks=[]):
      for exit_mask in exit_masks:
        if exit_mask[point[1]][point[0]] == 255:
          return True
      return False
    def draw_pathes(self, img, pathes):
      if not img.any():
        return
      for i, path in enumerate(pathes):
        path = np.array(path)[:, 1].tolist()
        for point in path:
          cv2.circle(img, point, 2, CAR_COLOURS[0], -1)
          cv2.polylines(img, [np.int32(path)], False, CAR_COLOURS[0], 1)
      return img
    def draw_boxes(self, img, pathes, exit_masks=[]):
      for (i, match) in enumerate(pathes):
        contour, centroid = match[-1][:2]
        if self.check_exit(centroid, exit_masks):
          continue
        x, y, w, h = contour
        cv2.rectangle(img, (x, y), (x + w - 1, y + h - 1),
               BOUNDING_BOX_COLOUR, 1)
        cv2.circle(img, centroid, 2, CENTROID_COLOUR, -1)
      return img
    def draw_ui(self, img, vehicle_count, exit_masks=[]):
      # this just add green mask with opacity to the image
      for exit_mask in exit_masks:
        _img = np.zeros(img.shape, img.dtype)
        _img[:, :] = EXIT_COLOR
        mask = cv2.bitwise_and(_img, _img, mask=exit_mask)
        cv2.addWeighted(mask, 1, img, 1, 0, img)
      # drawing top block with counts
      cv2.rectangle(img, (0, 0), (img.shape[1], 50), (0, 0, 0), cv2.FILLED)
      cv2.putText(img, ("Vehicles passed: {total} ".format(total=vehicle_count)), (30, 30),
            cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 1)
      return img
    def __call__(self, context):
      frame = context['frame'].copy()
      frame_number = context['frame_number']
      pathes = context['pathes']
      exit_masks = context['exit_masks']
      vehicle_count = context['vehicle_count']
      frame = self.draw_ui(frame, vehicle_count, exit_masks)
      frame = self.draw_pathes(frame, pathes)
      frame = self.draw_boxes(frame, pathes, exit_masks)
      utils.save_frame(frame, self.image_dir +
               "/processed_%04d.png" % frame_number)
      return context

结论

正如我们看到的那样,它并不像许多人想象的那么难。但是,如果小伙伴运行脚本,小伙伴会发现此解决方案并不理想,存在前景对象存在重叠的问题,并且它也没有按类型对车辆进行分类。但是,当相机有较好位置,例如位于道路正上方时,该算法具有很好的准确性。

到此这篇关于使用OpenCV实现道路车辆计数的使用方法的文章就介绍到这了,更多相关OpenCV 道路车辆计数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python+OpenCV实现车牌字符分割和识别

    最近做一个车牌识别项目,入门级别的,十分简单. 车牌识别总体分成两个大的步骤: 一.车牌定位:从照片中圈出车牌 二.车牌字符识别 这里只说第二个步骤,字符识别包括两个步骤: 1.图像处理 原本的图像每个像素点都是RGB定义的,或者称为有R/G/B三个通道.在这种情况下,很难区分谁是背景,谁是字符,所以需要对图像进行一些处理,把每个RGB定义的像素点都转化成一个bit位(即0-1代码),具体方法如下: ①将图片灰度化 名字拗口,但是意思很好理解,就是把每个像素的RGB都变成灰色的RGB值,而灰色的

  • python+opencv实现车牌定位功能(实例代码)

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验三,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验三. 由于时间紧张,代码没有进行任何优化,实验算法仅供参考. 实验要求 对给定的车牌进行车牌识别 实验代码 代码首先贴在这里,仅供参考 源代码 实验代码如下: import cv2 import numpy as np def lpr(filename): img = cv2.imread(filename) # 预处理,包括灰度处理,高斯

  • python+OpenCV实现车牌号码识别

    基于python+OpenCV的车牌号码识别,供大家参考,具体内容如下 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分:车辆图像获取.车牌定位.车牌字符分割和车牌字符识别 1.车牌定位的主要工作是从获取的车辆图像中找到汽车牌照所在位置,并把车牌从该区域中准确地分割出来 这里所采用的是利用车牌的颜色(黄色.蓝色.绿色) 来进行定位 #定位车牌 def color_position(img,ou

  • OpenCV+Python识别车牌和字符分割的实现

    本篇文章主要基于python语言和OpenCV库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里不做介绍,可以自行安装配置! 车牌号检测需要大致分为四个部分: 1.车辆图像获取 2.车牌定位. 3.车牌字符分割 4.车牌字符识别 具体介绍 车牌定位需要用到的是图片二值化为黑白后进canny边缘检测后多次进行开运算与闭运算用于消除小块的区域,保留大块的区域,后用cv2.rectangle选取矩形框,从而定位车牌位置 车牌字符的分割前需要准备的是只保留车牌

  • android端使用openCV实现车牌检测

    现在,汽车的踪影无处不在,公路上疾驰,大街边临停,小区中停靠,车库里停泊.管理监控如此庞大数量的汽车是个头疼的问题.精明的人们把目光放在车牌上,因为车牌是汽车的"身份证".所以车牌识别成为了焦点,而车牌检测是车牌识别的基础和前提.本篇文章,主要讨论使用openCV实现车牌检测. openCV是开源计算机视觉库,基于计算机视觉与机器学习,提供强大的图像处理能力.我们可以快速集成openCV库到android端,其中一种方式是直接安装openCV Manager,按需使用:启动服务去动态加

  • opencv车道线检测的实现方法

    车道线检测,需要完成以下功能: 图像裁剪:通过设定图像ROI区域,拷贝图像获得裁剪图像 反透视变换:用的是室外采集到的视频,没有对应的变换矩阵.所以建立二维坐标,通过四点映射的方法计算矩阵,进行反透视变化.后因ROI区域的设置易造成变换矩阵获取困难和插值得到的透视图效果不理想,故没应用 二值化:先变化为灰度图,然后设定阈值直接变成二值化图像. 形态学滤波:对二值化图像进行腐蚀,去除噪点,然后对图像进行膨胀,弥补对车道线的腐蚀. 边缘检测:canny变化.sobel变化和laplacian变化中选

  • 使用OpenCV实现检测和追踪车辆

    本文实例为大家分享了OpenCV实现检测和追踪车辆的具体代码,供大家参考,具体内容如下 完整源码GitHub 使用高斯混合模型(BackgroundSubtractorMOG2)对背景建模,提取出前景 使用中值滤波去掉椒盐噪声,再闭运算和开运算填充空洞 使用cvBlob库追踪车辆,我稍微修改了cvBlob源码来通过编译 由于要对背景建模,这个方法要求背景是静止的 另外不同车辆白色区域不能连通,否则会认为是同一物体 void processVideo(char* videoFilename) {

  • 使用OpenCV对车道进行实时检测的实现示例代码

    项目介绍 下图中的两条线即为车道: 我们的任务就是通过 OpenCV 在一段视频(或摄像头)中实时检测出车道并将其标记出来.其效果如下图所示: 这里使用的代码来源于磐怼怼大神,此文章旨在对其代码进行解释. 实现步骤 1.将视频的所有帧读取为图片: 2.创建掩码并应用到这些图片上: 3.图像阈值化: 4.用霍夫线变换检测车道: 5.将车道画到每张图片上: 6.将所有图片合并为视频. 代码实现 1.导入需要的库 import os import re import cv2 import numpy

  • 使用OpenCV实现道路车辆计数的使用方法

    今天,我们将一起探讨如何基于计算机视觉实现道路交通计数. 在本教程中,我们将仅使用Python和OpenCV,并借助背景减除算法非常简单地进行运动检测. 我们将从以下四个方面进行介绍: 1. 用于物体检测的背景减法算法主要思想. 2. OpenCV图像过滤器. 3. 利用轮廓检测物体. 4. 建立进一步数据处理的结构. 背景扣除算法 有许多不同的背景扣除算法,但是它们的主要思想都很简单. 假设有一个房间的视频,在某些帧上没有人和宠物,那么此时的视频基本为静态的,我们将其称为背景(backgrou

  • python+opencv图像分割实现分割不规则ROI区域方法汇总

    在图像分割领域,一个重要任务便是分割出感兴趣(ROI)区域.如果是简易的矩形ROI区域其实是非常容易分割的,opencv的官方python教程里也有教到最简易的矩形ROI分割(剪裁),其本质是多维数组(矩阵)的切片.但是现实情况中,ROI是不规则的多边形,也可能是曲线边界,那么该如何分割出来呢?下面总结几种思路. 可能只提供核心部分的代码示例,具体应用要结合你自己的项目来修正. 一.已知边界坐标,直接画出多边形 例:最基础的画个四边形 # 定义四个顶点坐标 pts = np.array([[10

  • Python OpenCV 直方图的计算与显示的方法示例

    本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了.这里直接介绍方法. 计算并显示直方图 与C++中一样,在Python中调用的OpenCV直方图计算函数为cv2.calcHist. cv2.calcHist的原型为: cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) #返回his

  • python OpenCV学习笔记之绘制直方图的方法

    本篇文章主要介绍了python OpenCV学习笔记之绘制直方图的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 官方文档 – https://docs.opencv.org/3.4.0/d1/db7/tutorial_py_histogram_begins.html 直方图会让你对图像的强度分布有一个全面的认识.它是一个在x轴上带有像素值(从0到255,但不总是),在y轴上的图像中对应的像素数量的图. 这只是理解图像的另一种方式.通过观察图像的直方图,你可以直

  • opencv改变imshow窗口大小,窗口位置的方法

    如下所示: cv2.HoughLinesP cv2.namedWindow("enhanced",0); cv2.resizeWindow("enhanced", 640, 480); cv2.imshow("enhanced",lines) cv2.waitKey(0) 创建窗口时候改变下参数就可以鼠标随意拖动窗口改变大小啦 cv::namedWindow("camera", CV_WINDOW_NORMAL);//CV_W

  • python下的opencv画矩形和文字注释的实现方法

    画矩形 函数调用:cv2.rectangle(img,pt1,pt2,color,thickness,line_type,shift) img: 图像. pt1: 矩形的一个顶点. pt2: 矩形对角线上的另一个顶点 color: 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image). thickness: 组成矩形的线条的粗细程度.取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形. line_type: 线条的类型.见cvLine的描述 shift: 坐标点的

  • python用opencv批量截取图像指定区域的方法

    代码如下 import os import cv2 for i in range(1,201): if i==169 or i==189: i = i+1 pth = "C:\\Users\\Desktop\\asd\\"+str(i)+".bmp" image = cv2.imread(pth) //从指定路径读取图像 cropImg = image[600:1200,750:1500] //获取感兴趣区域 cv2.imwrite("C:\\Users\

  • 在python中利用opencv简单做图片比对的方法

    下面代码中利用了两种比对的方法,一 对图片矩阵(m x m)求解特征值,通过比较特征值是否在一定的范围内,判断图片是否相同.二 对图片矩阵(m x m)中1求和,通过比较sum和来比较图片. # -*- coding: utf-8 -*- import cv2 as cv import numpy as np import os file_dir_a='C:\Users\wt\Desktop\data\image1\\' file_dir_b='C:\Users\wt\Desktop\data\

  • 利用pandas进行大文件计数处理的方法

    Pandas读取大文件 要处理的是由探测器读出的脉冲信号,一组数据为两列,一列为时间,一列为脉冲能量,数据量在千万级,为了有一个直接的认识,先使用Pandas读取一些 import pandas as pd data = pd.read_table('filename.txt', iterator=True) chunk = data.get_chunk(5) 而输出是这样的: Out[4]: 332.977889999979 -0.0164794921875 0 332.97790 -0.02

  • Python OpenCV招商银行信用卡卡号识别的方法

    学在前面 从本篇博客起,我们将实际完成几个小案例,第一个就是银行卡号识别,预计本案例将写 5 篇左右的博客才可以完成,一起加油吧. 本文的目标是最终获取一套招商银行卡,0~9 数字的图,对于下图的数字,我们需要提取出来,便于后续模板匹配使用.不过下图中找到的数字不完整,需要找到尽量多的卡片,然后补齐这些数字. 提取卡片相关数字 先对上文中卡片中的数字进行相关提取操作,加载图片的灰度图,获取目标区域.在画板中模拟一下坐标区域,为了便于进行后续的操作. 具体代码如下: import cv2 as c

随机推荐