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