用OpenCVFunction calcHis快速计算vdisparity

2024-10-03 04:29:37 发布

您现在位置:Python中文网/ 问答频道 /正文

基于一个来自被动立体相机系统的视差矩阵,我需要计算一个v视差表示,用于使用OpenCV进行障碍物检测。在

一个有效的实现并不是问题所在。问题是要做得快。。。在

(一)v视差参考文献:Labayrade,R.和Aubert,D.和Tarel,J.p.
通过v视差表示在非平坦道路几何体上进行立体视觉中的实时障碍物检测

简而言之,要得到v视差(图1),基本的是分析视差矩阵的行(图2),并将结果表示为视差值上每行的直方图。u-视差(图3)在视差矩阵的列上是相同的。(所有数字均为假彩色。)

<>我在Python和C++中实现了“相同”。Python中的速度是可以接受的,但是在C++中,我得到U和V视差大约一秒半(0.5秒)。在

(1。编辑:由于单独的时间测量,只有计算u-直方图需要大量的时间…

这就引出了以下问题:

  1. 是否可以避免柱状图逐行计算的循环?在OpenCV中调用一个calcHist-函数有什么“诀窍”吗?也许是尺寸?

  2. >P>是C++中的坏编码,运行时问题与计算循环无关吗?

谢谢大家


Python中的工作实现:

#!/usr/bin/env python2
#-*- coding: utf-8 -*-
#
# THIS SOURCE-CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED. IN NO  EVENT WILL THE AUTHOR BE HELD LIABLE FOR ANY DAMAGES ARISING FROM
# THE USE OF THIS SOURCE-CODE. USE AT YOUR OWN RISK.

import cv2
import numpy as np
import time

def draw_object(image, x, y, width=50, height=100):
    color = image[y, x]
    image[y-height:y, x-width//2:x+width//2] = color


IMAGE_HEIGHT = 600
IMAGE_WIDTH = 800

while True:

    max_disp = 200

    # create fake disparity
    image = np.zeros((IMAGE_HEIGHT, IMAGE_WIDTH), np.uint8)

    for c in range(IMAGE_HEIGHT)[::-1]:
        image[c, ...] = int(float(c) / IMAGE_HEIGHT * max_disp)

    draw_object(image, 275, 175)
    draw_object(image, 300, 200)
    draw_object(image, 100, 350)

    # calculate v-disparity
    vhist_vis = np.zeros((IMAGE_HEIGHT, max_disp), np.float)
    for i in range(IMAGE_HEIGHT):
        vhist_vis[i, ...] = cv2.calcHist(images=[image[i, ...]], channels=[0], mask=None, histSize=[max_disp],
                                         ranges=[0, max_disp]).flatten() / float(IMAGE_HEIGHT)


    vhist_vis = np.array(vhist_vis * 255, np.uint8)
    vblack_mask = vhist_vis < 5
    vhist_vis = cv2.applyColorMap(vhist_vis, cv2.COLORMAP_JET)
    vhist_vis[vblack_mask] = 0

    # calculate u-disparity
    uhist_vis = np.zeros((max_disp, IMAGE_WIDTH), np.float)
    for i in range(IMAGE_WIDTH):
        uhist_vis[..., i] = cv2.calcHist(images=[image[..., i]], channels=[0], mask=None, histSize=[max_disp],
                                         ranges=[0, max_disp]).flatten() / float(IMAGE_WIDTH)

    uhist_vis = np.array(uhist_vis * 255, np.uint8)
    ublack_mask = uhist_vis < 5
    uhist_vis = cv2.applyColorMap(uhist_vis, cv2.COLORMAP_JET)
    uhist_vis[ublack_mask] = 0


    image = cv2.applyColorMap(image, cv2.COLORMAP_JET)


    cv2.imshow('image', image)

    cv2.imshow('vhist_vis', vhist_vis)
    cv2.imshow('uhist_vis', uhist_vis)

    cv2.imwrite('disparity_image.png', image)
    cv2.imwrite('v-disparity.png', vhist_vis)
    cv2.imwrite('u-disparity.png', uhist_vis)


    if chr(cv2.waitKey(0)&255) == 'q':
        break

C++中的工作实现:

^{pr2}$

enter image description here 图1:v-视差

fake disparity matrix 图2:假视差矩阵

enter image description here 图3:u形视差


  1. 编辑:
    • 在c++示例中,u和v视差和独立时间测量的正确名称
    • 小字体

Tags: imagenpmaskfloatwidthcv2vismax
2条回答

今天我有可能重新调查这个问题。记住了Mat-结构的OpenCV基础知识(1),以及只有一个计算需要大量时间的事实,我就有了解决方案。在

在OpenCV中,一个行指针可以访问图像的每一行。对于迭代列(在u视差计算中完成),我怀疑OpenCV需要解析每个行指针+列偏移量来构建直方图。在

通过改变代码的方式,OpenCV能够使用行指针,为我解决了这个问题。在

            | old code [s] | changed [s]
      +       +      -
V-HIST-TIME | 0.00351909   | 0.00334152
U-HIST-TIME | 0.600039     | 0.00449285

所以对于u-hist-loop,我将图像转置,并在循环之后反转操作。现在可以通过行指针进行计算的行访问。在

更改的代码行:

^{pr2}$

最后,我的第二个问题生效了,运行时问题不属于循环。不到5毫秒的时间足够快了。在

非常好的代码和说明。它帮助我理解了u型差异。但是,您的C/C++代码被破坏了。我用这个密码把他治好了:

cv::Mat uhist = cv::Mat::zeros(MAX_DISP, IMAGE_WIDTH, CV_32F);
cv::Mat vhist = cv::Mat::zeros(IMAGE_WIDTH, MAX_DISP, CV_32F); 

相关问题 更多 >