Понимание Rect в OpenCV C++

Я пытаюсь отметить пиксели внутри прямоугольника. Отмечаемый прямоугольник определяется в конструкции if-else. Я получаю следующую ошибку при использовании прямоугольников, которые определены в любом из блоков if-else: «Утверждение не выполнено (0 ‹= roi.x && 0 ‹ = roi.width && roi.x + roi.width ‹=m. cols && 0 ‹=roi.height && roi.y +roi.height ‹= m.rows)"

Вот фрагмент кода, который я использую:

if (faces.size() != 0){r = faces[0];}
if (eyes.size()!=0){r2 = eyes[0];}

markers(image.rows,image.cols)
if(faces.size() == 0){
    cout << "No Face found";
    rectangle_face = rectangle_old;
    rectangle_inner = rectangle_inner_old;
    rectangle_outer = rectangle_outer_old;
}
else {
    pt1.x = r.x;
    pt1.y = r.y;
    pt2.x = pt1.x + r.width;
    pt2.y = pt2.y + r.height;

    pt1_inner.x = r.x + (r.width)/3;
    pt1_inner.y = r.y + (r.height)/3;
    pt1_outer.x = pt1.x;
    pt1_outer.y = pt1.y;

    pt2_inner.x = pt2.x - (r.width)/3;
    pt2_inner.y = pt2.y - (r.height)/3;
    pt2_outer.x = pt2.x;
    pt2_outer.y = image.rows;

    rectangle_face = r; 
    rectangle_inner = Rect(pt1_inner,pt2_inner); 
    rectangle_outer = Rect(pt2_outer,pt2_outer);
}


//rectangle_inner = Rect(pt1_inner,pt2_inner); 
//rectangle_outer = Rect(pt2_outer,pt2_outer);

rectangle_old = rectangle_face;
rectangle_outer_old = rectangle_outer;
rectangle_inner_old = rectangle_inner;



// Setting all pixels to possible background first
markers.setTo(cv::GC_PR_BGD);

//It get stuck at the following two lines
cv::Mat1b fg_seed_inside_face = markers(rectangle_inner);
//Marking pixels in order. Note: Order is important here.
cv::Mat1b Prfg_seed_FaceExtended = markers(rectangle_outer);

'faces' - это вектор прямоугольников, возвращенный из detectMultiScale. Что меня сбивает с толку, так это то, что если я объявлю прямоугольник_внутренний и прямоугольник_аутер вне блоков if-else (как это прокомментировано во фрагменте кода, прямо под условием else), код отлично работает в случае, когда условие «если» не правда. Таким образом, в основном я должен объявить свои прямоугольники прямоугольника_внутреннего и прямоугольника снаружи блоков if-else, что не имеет смысла. Есть ли обходной путь?


person TheBlueNotebook    schedule 09.07.2014    source источник
comment
if((0 ‹= roi.x ) && (0 ‹ = roi.width) && ((roi.x + roi.width) ‹=m.cols ) && (0 ‹= roi.y ) && (0 ‹= roi.height ) && ((roi.y +roi.height )‹= m.rows))   -  person Prasaathviki    schedule 09.07.2014
comment
Я сожалею. Не совсем понял ваш ответ. Можете ли вы уточнить?   -  person TheBlueNotebook    schedule 09.07.2014


Ответы (1)


Когда вы вычисляете (x, y) координаты вашей внутренней и внешней точек для построения прямоугольников, вы должны проверить, что координаты, которые вы получаете, добавляя или вычитая из pt1 или pt2 r.weight или r.height, не выйти из образа. Это довольно распространенное явление, когда ваше лицо находится близко к краю вашего изображения.

Это можно легко сделать, выполнив что-то вроде

pt1.x = r.x;
pt1.y = r.y;
pt2.x = pt1.x + r.width;
if(pt2.x >= image.cols) //check that coordinate pt2.x doesn't get out of the image
    pt2.x = image.cols;

pt2.y = pt2.y + r.height;
if(pt2.y >= image.rows) //check that coordinate pt2.y doesn't get out of the image
    pt2.y = image.rows;

И повторите проверку для каждой координаты, которую вы вычисляете. Когда вы вычитаете, просто проверьте, что координаты >= 0, и установите их на 0, если это не так.

Надеюсь, поможет..

person powder    schedule 09.07.2014
comment
Привет, я подозревал то же самое и проверил его. Координаты, выходящие за пределы диапазона, не проблема. Я напечатал координаты прямоугольника_внутреннего и прямоугольника_внешнего, и оба они были в пределах диапазона. Кажется, проблема связана с тем, что я определяю прямоугольник_внутренний и прямоугольник_внешний внутри блока. Если я сделаю точно такие же определения вне блоков if/else, код будет работать правильно! - person TheBlueNotebook; 09.07.2014
comment
Итак, если вы проверили координаты в другом, я предполагаю, что проблема может быть в первом if(faces.size() == 0){ .. вы проверили значения rectangle_inner_old и rectangle_outer_old? Не должно быть никакой разницы в присвоении значений внутри или вне блока if, поэтому проблема должна быть в другом месте. - person powder; 09.07.2014
comment
Я проверил и их. Вот почему это сбивает меня с толку. Из предыдущей программы я знаю, что для первых нескольких кадров видео, которое я использую, Faces.size()!=0. Кроме того, когда я раскомментирую объявление за пределами блока else, программа хорошо работает для первых нескольких кадров, где происходит обнаружение лица. После этого выдает ту же ошибку. - person TheBlueNotebook; 09.07.2014
comment
Мне жаль. Я ошибался. Есть проблема с самим диапазоном значений. Но пока не могу исправить. По какой-то причине детектор лиц возвращает прямоугольник, верхняя правая точка которого находится за пределами кадра. Я применю проверку, которую вы предложили дальше. - person TheBlueNotebook; 09.07.2014
comment
Чтобы настроить прямоугольник, вы можете сделать что-то вроде этого: cv::Rect imageRect(0,0, imWidth,imHeight); adjustedRect = yourRect & imageRect; - person Micka; 10.07.2014