Ask Your Question

Revision history [back]

Hi,

I think it is better to fit a Triangle than a Square for your use case. I'll ass the code for fitting the Rotated Rectangle in the above partition when i get time! Hope this gives you some rough idea!

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

void Erode(InputArray mSrc, OutputArray mDst, int erosion_size, int erosion_elem)
{
    int erosion_type = 0;
    if (erosion_elem == 0){ erosion_type = MORPH_RECT; }
    else if (erosion_elem == 1){ erosion_type = MORPH_CROSS; }
    else if (erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

    //![kernel]
    Mat element = getStructuringElement(erosion_type,
        Size(2 * erosion_size + 1, 2 * erosion_size + 1),
        Point(erosion_size, erosion_size));

    /// Apply the erosion operation
    erode(mSrc, mDst, element);
}

void Dilate(InputArray mSrc, OutputArray mDst, int dilate_size, int dilate_elem)
{
    int dilate_type = 0;
    if (dilate_elem == 0){ dilate_type = MORPH_RECT; }
    else if (dilate_elem == 1){ dilate_type = MORPH_CROSS; }
    else if (dilate_elem == 2) { dilate_type = MORPH_ELLIPSE; }

    //![kernel]
    Mat element = getStructuringElement(dilate_type,
        Size(2 * dilate_size + 1, 2 * dilate_size + 1),
        Point(dilate_size, dilate_size));

    /// Apply the erosion operation
    dilate(mSrc, mDst, element);
}

int main(int argc, char* argv[])
{
    string FileName_S = "Input.png";

    Mat mSource= imread(FileName_S,0), 
        mAlphaMat,mForegroundMask,mResult;

    if (mSource.empty())
    {
        cout << "[Error] Invalid Input Image!";
        return 0;
    }

    //Source Image
    imshow("Input Image", mSource);

image description

    //Extract the Alpha Mask that we are interested in
    inRange(mSource, 128, 128, mAlphaMat);

    //Extract the Foreground Mask too
    inRange(mSource, 255, 255, mForegroundMask);

    //Choose the Size of the Intersection Area
    const int SIZE_WIDTH = 5;

    //Grow the White region by Dilating the Alpha Mask
    Dilate(mAlphaMat, mAlphaMat, SIZE_WIDTH, 1);

    imshow("Alpha Mask + Dilate", mAlphaMat);

image description

    //Just for Visualisation purpose
    mSource.copyTo(mResult, mAlphaMat);
    cvtColor(mResult, mResult, COLOR_GRAY2BGR);

    //Find the Centre of the Foreground Mask to Start Partition in a Circle
    //Credits: http://answers.opencv.org/question/56095/draw-lines-from-centroid-of-contour-at-given-angle-till-edge-of-contour/#56254
    Moments Moments = moments(mForegroundMask);
    Point Centre(int(Moments.m10 / Moments.m00), int(Moments.m01 / Moments.m00));
    Rect bounds(0, 0, mResult.cols, mResult.rows);

    for (int Angle = 0; Angle<360; Angle += 20)
    {
        //Find another point in the circle with some offset! We just need the direction!
        Point Point2(Centre.x + sin(Angle*CV_PI / 180) * 500, Centre.y + cos(Angle*CV_PI / 180) * 500);

        //Iterate through the Line till the Image Boundary
        LineIterator Line_Itr(mResult, Centre, Point2, 8);

        //Draw the Line at each step till it reaches Image Boundary
        while (bounds.contains(Line_Itr.pos()) && (Line_Itr.pos().x>0 &&Line_Itr.pos().y>0))
        {
            mResult.at<Vec3b>(Line_Itr.pos()) = Vec3b(0, 255, 0);
            Line_Itr++;
        }
    }

    imshow("Result", mResult);

image description

    waitKey();

}

Hi,

I think it is better to fit a Triangle than a Square for your use case. I'll ass the code for fitting the Rotated Rectangle in the above partition when i get time! Hope case.Hope this gives you some rough idea!idea! We can partition the Alpha mask based on these initial cuts. I will add the later part in sometime.

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

void Erode(InputArray mSrc, OutputArray mDst, int erosion_size, int erosion_elem)
{
    int erosion_type = 0;
    if (erosion_elem == 0){ erosion_type = MORPH_RECT; }
    else if (erosion_elem == 1){ erosion_type = MORPH_CROSS; }
    else if (erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

    //![kernel]
    Mat element = getStructuringElement(erosion_type,
        Size(2 * erosion_size + 1, 2 * erosion_size + 1),
        Point(erosion_size, erosion_size));

    /// Apply the erosion operation
    erode(mSrc, mDst, element);
}

void Dilate(InputArray mSrc, OutputArray mDst, int dilate_size, int dilate_elem)
{
    int dilate_type = 0;
    if (dilate_elem == 0){ dilate_type = MORPH_RECT; }
    else if (dilate_elem == 1){ dilate_type = MORPH_CROSS; }
    else if (dilate_elem == 2) { dilate_type = MORPH_ELLIPSE; }

    //![kernel]
    Mat element = getStructuringElement(dilate_type,
        Size(2 * dilate_size + 1, 2 * dilate_size + 1),
        Point(dilate_size, dilate_size));

    /// Apply the erosion operation
    dilate(mSrc, mDst, element);
}

int main(int argc, char* argv[])
{
    string FileName_S = "Input.png";

    Mat mSource= imread(FileName_S,0), 
        mAlphaMat,mForegroundMask,mResult;

    if (mSource.empty())
    {
        cout << "[Error] Invalid Input Image!";
        return 0;
    }

    //Source Image
    imshow("Input Image", mSource);

image description

    //Extract the Alpha Mask that we are interested in
    inRange(mSource, 128, 128, mAlphaMat);

    //Extract the Foreground Mask too
    inRange(mSource, 255, 255, mForegroundMask);

    //Choose the Size of the Intersection Area
    const int SIZE_WIDTH = 5;

    //Grow the White region by Dilating the Alpha Mask
    Dilate(mAlphaMat, mAlphaMat, SIZE_WIDTH, 1);

    imshow("Alpha Mask + Dilate", mAlphaMat);

image description

    //Just for Visualisation purpose
    mSource.copyTo(mResult, mAlphaMat);
    cvtColor(mResult, mResult, COLOR_GRAY2BGR);

    //Find the Centre of the Foreground Mask to Start Partition in a Circle
    //Credits: http://answers.opencv.org/question/56095/draw-lines-from-centroid-of-contour-at-given-angle-till-edge-of-contour/#56254
    Moments Moments = moments(mForegroundMask);
    Point Centre(int(Moments.m10 / Moments.m00), int(Moments.m01 / Moments.m00));
    Rect bounds(0, 0, mResult.cols, mResult.rows);

    for (int Angle = 0; Angle<360; Angle += 20)
    {
        //Find another point in the circle with some offset! We just need the direction!
        Point Point2(Centre.x + sin(Angle*CV_PI / 180) * 500, Centre.y + cos(Angle*CV_PI / 180) * 500);

        //Iterate through the Line till the Image Boundary
        LineIterator Line_Itr(mResult, Centre, Point2, 8);

        //Draw the Line at each step till it reaches Image Boundary
        while (bounds.contains(Line_Itr.pos()) && (Line_Itr.pos().x>0 &&Line_Itr.pos().y>0))
        {
            mResult.at<Vec3b>(Line_Itr.pos()) = Vec3b(0, 255, 0);
            Line_Itr++;
        }
    }

    imshow("Result", mResult);

image description

    waitKey();

}