اگر ابعاد تصویر شما خیلی بزرگه می تونید در ابتدا تصویر را down sample کنید با انجام اینکار هم نویز ها از تصویر حذف میشه و هم ابعاد تصویر کوچکتر میشه و نتیجه آن یعنی پردازش سریع تر.چون خطوط شما در تصویر لبه های تیزی دارند شما نیازی ندارید که حتما به طو خاص لبه های افقی و عمودی را نمایان کنید با اعمال لبه یاب canny روی تصویر خطوط را بدست بیارید.
cv::Canny(bw, bw, 100, 100, 3);
بعد از این با تبدیل هاف خطی تمامی خطوط را در صفحه بدست بیارید از مدل هاف تصادفی استفاده کنید که دارای کارایی بالاتری هستش .
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(bw, lines, 1, CV_PI/180, 70, 30, 10);
در انتها هم تقاطع دادن خطوط و بدست آوردن گوشه هر یک از rectangle های موجود در تصویر در تصویر قرار داده شده شما نیاز به استفاده از تبدیل perspective ندارید فقظ بایستی از تبدیل affine برای چرخش هر یک از rectangle ها استفاده نمائید.
cv::Point2f computeIntersect(cv::Vec4i a, cv::Vec4i b)
{
int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3];
int x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
if (float d = ((float)(x1-x2) * (y3-y4)) - ((y1-y2) * (x3-x4)))
{
cv::Point2f pt;
pt.x = ((x1*y2 - y1*x2) * (x3-x4) - (x1-x2) * (x3*y4 - y3*x4)) / d;
pt.y = ((x1*y2 - y1*x2) * (y3-y4) - (y1-y2) * (x3*y4 - y3*x4)) / d;
return pt;
}
else
return cv::Point2f(-1, -1);
}
...
std::vector<cv::Point2f> corners;
for (int i = 0; i < lines.size(); i++)
{
for (int j = i+1; j < lines.size(); j++)
{
cv::Point2f pt = computeIntersect(lines[i], lines[j]);
if (pt.x >= 0 && pt.y >= 0)
corners.push_back(pt);
}
}