1 | initial version |
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);
//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);
//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);
waitKey();
}
2 | No.2 Revision |
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);
//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);
//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);
waitKey();
}