採用中心往外擴張的方法,目前是特定的場景下使用。
bool expandEdge(const Mat & img, int edge[], const int edgeID, bool EXPAND[])
{
//[1] --初始化參數
int nc = img.cols;
int nr = img.rows;
switch (edgeID) {
case 0:
if (edge[0]>nr || EXPAND[0] == false)
return false;
for (int i = edge[3] + 1; i < edge[1]; ++i)
{
if (img.at<uchar>(edge[0], i) == 0)//遇見0像素表明碰到邊緣線
{
return false;
}
}
edge[0]++;
return true;
break;
case 1:
if (edge[1]>nc || EXPAND[1] == false)
return false;
for (int i = edge[2] + 1; i < edge[0]; ++i)
{
if (img.at<uchar>(i, edge[1]) == 0)//遇見0像素表明碰到邊緣線
{
return false;
}
}
edge[1]++;
return true;
break;
case 2:
if (edge[2]<0 || EXPAND[2] == false)
return false;
for (int i = edge[3] + 1; i < edge[1]; ++i)
{
if (img.at<uchar>(edge[2], i) == 0)//遇見0像素表明碰到邊緣線
{
return false;
}
}
edge[2]--;
return true;
break;
case 3:
if (edge[3]<0 || EXPAND[3] == false)
return false;
for (int i = edge[2] + 1; i < edge[0]; ++i)
{
if (img.at<uchar>(i, edge[3]) == 0)//遇見0像素表明碰到邊緣線
{
return false;
}
}
edge[3]--;
return true;
break;
default:
return false;
break;
}
}
cv::Rect InSquare(Mat &img, const Point center)
{
// --[1]參數檢測
if (img.empty() || img.channels()>1 || img.depth()>8)
return Rect();
// --[2] 初始化變量
int edge[4];
edge[0] = center.y + 1;//top
edge[1] = center.x + 1;//right
edge[2] = center.y - 1;//bottom
edge[3] = center.x - 1;//left
//[2]
// --[3]邊界擴展(中心擴散法)
bool EXPAND[4] = { 1,1,1,1 };//擴展標記位
int n = 0;
while (EXPAND[0] || EXPAND[1] || EXPAND[2] || EXPAND[3])
{
int edgeID = n % 4;
EXPAND[edgeID] = expandEdge(img, edge, edgeID, EXPAND);
n++;
}
//[3]
//qDebug() << edge[0] << edge[1] << edge[2] << edge[3];
Point tl = Point(edge[3], edge[0]);
Point br = Point(edge[1], edge[2]);
return Rect(tl, br);
}
int calcMaxCoheRect(Mat &srcMat, Rect &maxCoheRect)
{
//設置中心
if (srcMat.empty())
{
cout << "fali" << endl;
return 1;
}
Point center(srcMat.cols / 2, srcMat.rows / 2);
Rect rr = InSquare(srcMat, center);
maxCoheRect = rr;
return 0;
}
原圖:
結果: