استخراج مدارک مختلف از داخل تصویر اسکن شده از مدارک - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

استخراج مدارک مختلف از داخل تصویر اسکن شده از مدارک

+1 امتیاز

با سلام خدمت دوستان عزیز

مدت یک ماهی هست که بر روی برنامه ای کار میکنم که باید مدارک مختلفی رو از داخل تصویر اسکن شده استخراج کنه و در اخر تصاویر را ذخیره کنه تا حدی برنامه رو ئیش بردم :! ولی فکر میکنم خیلی حرفه ای نباشد به همین دلیل قصد دارم از ابتدا شروع کنم :!

نمونه تصویری که قرار هست مورد استفاده قرار بگیره در زیر قرار میدم :!

فرایندی که قصد دارم انجام بشه به این شکل هست

در مرحله اول بوسیله سوبل از تصویر مشتق افقی بگیریم تا لبه های عمودی تصویر مشخص شه. بعد از برش این نواحی از تصویر مشتق عمودی بگیریم تا لبه های افقی استخراج شه. در خر بوسیله Canyy و Findcontour کانتور های داخلی رو پیدا کرده و یکی یکی اونارو استخراج کنیم

روش مستق گیری افقی و عمودی جهت برش نواحی عمودی و افقی به چه شکل هست :؟

روش بدست اوردن کانتور ها بوسیه Canyy و Findcontour به چه شکل هست و چطور میتوان تک تک تصاویر رو استخراج کرده و کار تمیزی رو تحویل دا:؟

زاویه های تصاویر رو اصلاح کرد تا تصاویر دقیق و بدون انحراف داشت :؟

ممنون میشم از دوستان اگر کمک کنن :)

canyy, findcontour, سوبل

سوال شده مرداد 12, 1393  بوسیله ی m_yousefi1362 (امتیاز 12)   1 1 1
ویرایش شده دی 30, 1393 بوسیله ی haniye sarbazi

1 پاسخ

+4 امتیاز

اگر ابعاد تصویر شما خیلی بزرگه می تونید در ابتدا تصویر را 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);
    }
}
پاسخ داده شده مرداد 14, 1393 بوسیله ی مصطفی ساتکی (امتیاز 21,998)   24 34 75
ویرایش شده مرداد 14, 1393 بوسیله ی مصطفی ساتکی
با تشکر جناب اقای ساتکی این کدی که شما نوشتید با جه زبانی بود :؟ c++ d یا چی :؟ من از زبان C# h  استفاده می کنم به همراه فریم ورک افورگ در صورتی که بخوام با این زبان این الکوریتمی که فرمودین رو پیاده کنم به چه شکل باید عمل کنم :؟ با تشکر
دوست عزیز از  دیدگاه استفاده کنید نه  " پاسخ "
...