2015-12-01 1 views
0

У меня есть проект создания программы обнаружения лиц. Одним из требований является то, что я рисую линию по центру лица.Как вытянуть линию в OpenCV?

Теперь, как я это сделал, сначала рисуем линию через два глаза (получая координаты каждого глаза и используя их как точки линии), а затем рисуем перпендикулярную линию к этому. Таким образом, я также могу объяснить поворот лица.

Однако эта линия имеет ту же длину, что и линия на глазах. Я хочу, чтобы эта перпендикулярная линия пересекала все лицо, если это было возможно. Приложенный пример моего вывода для одного повернутого изображения лица. Мне нужно, чтобы зеленая линия была длиннее.

+0

Это зеленое значение, фиксированное для каждого изображения? будет inRange с этим значением rgb, даст вам хорошую сегментацию зеленой линии? – Micka

+0

@Micka Зеленая линия рассчитывается по-разному для каждого изображения. Линия - это просто центр лица. Я просто хочу, чтобы эта линия была длиннее. – Sheraz

+0

Я имею в виду цвет, это всегда то же самое значение rgb для зеленого цвета? – Micka

ответ

0

К сожалению, ваше изображение является 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

0

Ill записать его в псевдокоде

  • Возьмите дальний правый край координат (Row1, col1) в изображении
  • Возьмите правильную точку руки вашей линии (ROW2, col2)
  • Нарисуйте линию от вашей линии (row2, col2) до (row2, col1)
  • Повторите для левой стороны

Это приведет к нанесению двух дополнительных линий с обеих сторон вашей линии на край вашего изображения.

+1

Будет ли это не возвращаться в две вертикальные линии, вытекающие из концов исходной линии, эти линии не будут иметь тот же градиент, что и исходная зеленая линия? – Sheraz

 Смежные вопросы

  • Нет связанных вопросов^_^