A
A
Alexey Belov2019-06-07 19:54:21
Python
Alexey Belov, 2019-06-07 19:54:21

How to connect two paths in OpenCV?

Hello everyone, in general, there is an unusual task, I have a grid on tf that takes a photo with a haircut
5cfa954464dbd644646785.jpeg
AND gives out islands (what I counted as hair) on a transparent background. I take the largest outline (presumably a wig) and crop around it. But there is a problem, sometimes the photo is cut off from above, or for example, the girl has a very steep parting, because of this the wig is divided into two parts.
5cfa956088cf6976355118.png5cfa9a2391a49630535597.png
Here is the function

std::vector< int > gpuFindSides( InputArray image_mask )
{
    cuda::GpuMat image_mask_crop(image_mask);
    cuda::GpuMat mask_crop;
    cuda::GpuMat mask_crop_tr;
    cuda::GpuMat mask_crop_tr_8;
    Mat cropped_mask;
    
    cuda::threshold(image_mask_crop, mask_crop_tr, 0.1, 1.0, THRESH_BINARY);
    mask_crop_tr.convertTo(mask_crop_tr_8, CV_8UC1);
    mask_crop_tr_8.download(cropped_mask);

    std::vector<std::vector<Point> > contours;
    
    findContours(cropped_mask, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    double maxArea = 0;
    int maxAreaContourId = -1;
    int w;
    int h;
    for (int j = 0; j < contours.size(); j++) {
        double newArea = contourArea(contours.at(j));
        if (newArea > maxArea) {
            maxArea = newArea;
            maxAreaContourId = j;
        }
    }
    Rect rect = boundingRect(contours[maxAreaContourId]);
    w = rect.width;
    h = rect.height;
    if (h * 1.2 <= w) {
        h = (int)(h * 2);
    }
    else if (h <= w){
        h = (int)(h * 1.5);
    }
    else if (h * 0.8 <= w){
        h = (int)(h * 1.3);
    }

    std::vector< int > arr;

    arr.push_back(rect.x);
    arr.push_back(rect.y);
    arr.push_back(w);
    arr.push_back(h);
         
    return arr;
}

I don’t really understand the pros, so I would like to know how to make at least one of the options.
1. Connect all the contours and make one common, around which make a boundingRect.
2. Connect the two largest contours, but on condition that the difference in area is not more than 20-30%
3. Increase the threshold area, then the two parts of the wig can hook each other
The task is not easy, I don’t count on a solution, but I will be very happy with tips

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Belov, 2019-06-07
@Alenorze

The solution was to change the value of threshold from 0.1 to 0.01

G
grinat, 2019-06-07
@grinat

opencv has bindings for all known and unknown languages, I don't understand what prevents you from taking a binding for python or any other <language_name> and playing with it. If it's a wig that slips in instead of transparent pixels. then the areas are not needed, in theory, it is enough to get the x, y of the lower left first transparent pixel and starting from this position, draw a wig, then overlay a photo from above, in which all transparent pixels will be cut out.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question