【问题标题】:How to extend a drawn line in OpenCV?如何在 OpenCV 中延长画线?
【发布时间】:2016-03-05 13:28:38
【问题描述】:

我有一个创建人脸检测程序的项目。我的要求之一是在脸的中心画一条线。

现在我这样做的方法是首先在两只眼睛上画一条线(通过获取每只眼睛的坐标并将它们用作线点),然后画一条垂直线。这样我也可以考虑面部旋转。

但是,这条线与穿过眼睛的线的长度相同。如果可能的话,我希望这条垂直线穿过整个脸。附件是我的一个旋转面部图像的输出示例。我需要更长的绿线。

【问题讨论】:

  • 每个图像的绿色值是固定的吗?具有该 rgb 值的 inRange 会给你一个很好的绿线分割吗?
  • @Micka 对于每张图像,绿线的计算方式不同。这条线只是绘制的面的中心。我只是想要那条线更长。
  • 我的意思是颜色,绿色总是相同的 rgb 值吗?
  • 一开始就调整人脸检测代码画不一样不是更容易吗?

标签: c++ opencv drawing face-detection


【解决方案1】:

不幸的是,您的图像是 jpeg,因此它具有压缩伪影。

我第一次尝试提取线,但没有给出很好的角度信息,所以我在绿色区域分割后使用 cv::minAreaRect。

cv::Mat green;
cv::inRange(input, cv::Scalar(0,100,0), cv::Scalar(100,255,100),green);


// instead of this, maybe try to find contours and choose the right one, if there are more green "objects" in the image
std::vector<cv::Point2i> locations; 
cv::findNonZero(green, locations);

// find the used color to draw in same color later
cv::Vec3d averageColorTmp(0,0,0);
for(unsigned int i=0; i<locations.size(); ++i)
{
    averageColorTmp += input.at<cv::Vec3b>(locations[i]);
}
averageColorTmp *= 1.0/locations.size();

// compute direction of the segmented region
cv::RotatedRect line = cv::minAreaRect(locations);

// extract directions:
cv::Point2f start = line.center;
cv::Point2f rect_points[4];
line.points(rect_points);
cv::Point2f direction1 = rect_points[0] - rect_points[1];
cv::Point2f direction2 = rect_points[0] - rect_points[3];

// use dominant direction
cv::Point2f lineWidthDirection;
lineWidthDirection = (cv::norm(direction1) < cv::norm(direction2)) ? direction1 : direction2;
double lineWidth = cv::norm(lineWidthDirection);
cv::Point2f lineLengthDirection;
lineLengthDirection = (cv::norm(direction1) > cv::norm(direction2)) ? direction1 : direction2;
lineLengthDirection = 0.5*lineLengthDirection; // because we operate from center;

// input parameter:
// how much do you like to increase the line size?
// value of 1.0 is original size
// value of > 1 is increase of line
double scaleFactor = 3.0;

// draw the line
cv::line(input, start- scaleFactor*lineLengthDirection, start+ scaleFactor*lineLengthDirection, cv::Scalar(averageColorTmp[0],averageColorTmp[1],averageColorTmp[2]), lineWidth);

给出这个结果:

如果图像中没有其他绿色而只有绿线,则此方法应该非常稳健。如果图像中还有其他绿色部分,则应先提取轮廓并选择正确的轮廓分配变量locations

【讨论】:

    【解决方案2】:

    我会用伪代码写出来

    • 获取图像中最右边的边缘坐标 (row1,col1)
    • 取线的右侧点 (row2,col2)
    • 从您的线 (row2,col2) 到 (row2,col1) 画一条线
    • 在左侧重复

    这将导致从线条的任一侧到图像边缘绘制两条额外的线。

    【讨论】:

    • 这会不会导致两条垂直线从原始线的末端开始,这些线不会与原始绿线具有相同的渐变?
    猜你喜欢
    • 2013-05-17
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2012-10-21
    相关资源
    最近更新 更多