使用OpenCV在二值图像中绘制速度矢量

时间:2017-06-28 21:24:29

标签: c++ opencv vector

我有一个二进制(黑白)图像,我想在其上绘制一定速度的速度矢量。在MATLAB中,我们可以使用quiver绘制这些向量。我正在寻找使用C ++在OpenCV中解决此问题的方法。如果有人可以分享解决方案,我将不胜感激。尽管在SO(OpenCV How to Plot velocity vectors as arrows in using single static image)上使用静态图像提供了其中一种解决方案,但它还不清楚如何在二进制图像上实现它。如果有人能指导我,我将不胜感激。 期待对实施的一些建议。

2 个答案:

答案 0 :(得分:0)

这是我对你的问题的解决方案:在这个例子中,我从一个来自网络摄像头的rgb图像开始,然后我将其转换为灰度,然后在应用阈值后转换为二进制。

下一步,当您有二进制图像时,将再次将其转换为RGB(或BGR作为OpenCV约定)并在其上绘制您想要的任何内容。箭头的代码是您所链接的内容的副本。

希望有所帮助

cv::VideoCapture cam(n_source);
cam >> frame;

cv::Mat grey_image;
cv::Mat binary_image;  // Your binary image
cv::cvtColor(frame, grey_image, CV_RGB2GRAY);
cv::threshold(grey_image, binary_image, 100, 255, 0);

// Convert the binary to RGB
cv::Mat dst_rgb;
cv::cvtColor(binary_image, dst_rgb, CV_GRAY2BGR);

// Draw the arrow on the RGB image
int x = 200;
int y = 200;
int u = 100;
int v = 100;

cv::Point pt1,pt2;
double Theta;
double PI = 3.1416;

cv::Scalar Color(255,0,0);
int size = 5;
int Thickness = 5;

if(u==0)
    Theta=PI/2;
else
    Theta=atan2(double(v),(double)(u));

pt1.x=x;
pt1.y=y;

pt2.x=x+u;
pt2.y=y+v;

cv::line(dst_rgb,pt1,pt2,Color,Thickness,8);  //Draw Line


size=(int)(size*0.707);


if(Theta==PI/2 && pt1.y > pt2.y)
    {
    pt1.x=(int)(size*cos(Theta)-size*sin(Theta)+pt2.x);
    pt1.y=(int)(size*sin(Theta)+size*cos(Theta)+pt2.y);
    cv::line(dst_rgb,pt1,pt2,Color,Thickness,8);  //Draw Line

    pt1.x=(int)(size*cos(Theta)+size*sin(Theta)+pt2.x);
    pt1.y=(int)(size*sin(Theta)-size*cos(Theta)+pt2.y);
    cv::line(dst_rgb,pt1,pt2,Color,Thickness,8);  //Draw Line
  }
else{
    pt1.x=(int)(-size*cos(Theta)-size*sin(Theta)+pt2.x);
    pt1.y=(int)(-size*sin(Theta)+size*cos(Theta)+pt2.y);
    cv::line(dst_rgb,pt1,pt2,Color,Thickness,8);  //Draw Line

    pt1.x=(int)(-size*cos(Theta)+size*sin(Theta)+pt2.x);
    pt1.y=(int)(-size*sin(Theta)-size*cos(Theta)+pt2.y);
    cv::line(dst_rgb,pt1,pt2,Color,Thickness,8);  //Draw Line
}

// Plot
cv::namedWindow("test rgb");
cv::imshow("test rgb", dst_rgb);
cv::waitKey(0);

一个例子: blue line over binary image

答案 1 :(得分:0)

经过一番讨论后,我在OpenCV中遇到了cv :: arrowedLine,其中一个用法如下:

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>

 #include <opencv2/opencv.hpp>
 #include <opencv2/highgui.hpp>

  using namespace std;
  using namespace cv;

 int main(int argc, char* argv[])
 {
auto width = 320;
auto height = 320;
auto img = cv::Mat(cv::Size(width, height), CV_8UC3); // create background image

auto center = cv::Point(width / 2, height / 2); // center point

int lineType = 8;
int thickness = 1;
double tipLength = 0.1;

img.setTo(255);                          // clear image - set to black (0) or white (255)

for (int angle = 0; angle < 360; angle += 15)
{
    auto angleRad = angle*CV_PI / 180.0;   // convert angle to radians

    auto length = 150;
    auto direction = cv::Point(length * cos(angleRad), length * sin(angleRad)); // calculate direction
    tipLength = .01 + 0.4 * (angle % 180) / 360;

    cv::arrowedLine(img, center + direction*0.5, center + direction, CV_RGB(255, angle, 0), thickness, lineType, 0, tipLength); // draw arrow!

    ++thickness;
    if (0 == angle % 45)
        thickness = 0;

    if (180 <= angle)
        lineType = CV_AA;
}
imshow("Arrowed Image", img);          // show image
waitKey();

return EXIT_SUCCESS;
}