如何在OpenCV中扩展绘制的线?

时间:2015-12-01 15:08:21

标签: c++ opencv drawing face-detection

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

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

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

2 个答案:

答案 0 :(得分: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);

给出这个结果:

enter image description here

如果图像中没有其他绿色但只有绿线,则此方法应该非常强大。如果图像中还有其他绿色部分,则应首先提取轮廓并选择正确的轮廓以指定变量locations

答案 1 :(得分:0)

我用伪代码写出来

  • 使用图像中最右边的坐标(row1,col1)
  • 取你的右手点(第2行,第2列)
  • 从您的行(row2,col2)到(row2,col1)
  • 画一条线
  • 重复左侧

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