صد البته، اگر منظورتون با زبان #C ئه با چند تا حلقه می توانید لبه های کادر مستطیل رو تشخیص دهید و Crop کنید. البته اگر سرعت خیلی براتون ملاک نباشه تغییر رنگ زمینه به شفاف و چرخاندن کادر کج و ... هم عملی است.سلام وقت همگی به خیر
دوستان میخواستم بدونم آیا راهی وجود داره که بشه قسمتی از یک عکس اسکن شده که تصویر مورد نظر در اون وجود داره رو از قسمت های سفید تشخیص و برش داد ؟
مثلا در عکس زیر بتونه تصویر کارت ملی رو در صفحه تشخیص و برش بده :
خیلی ممنونم
private Image [B][COLOR="#0000FF"]CropImage[/COLOR][/B](Image image, Color background, Padding margin, double tolerance)
{
var bmp = (Bitmap)image;
var factorY = Math.Max((bmp.Height - margin.Vertical) / 20, 1);
var factorX = Math.Max((bmp.Width - margin.Horizontal) / 20, 1);
int x1, x2, y1, y2;
var finish = false;
for (x1 = margin.Left; (x1 < bmp.Width - margin.Right) && (finish == false); x1++)
{
for (int y = margin.Top; y < bmp.Height - margin.Bottom; y += factorY)
{
if (Tolerance(bmp.GetPixel(x1, y), background) > tolerance)
{
finish = true;
break;
}
}
}
finish = false;
for (x2 = bmp.Width - margin.Right; (x2 > margin.Left) && (finish == false); x2--)
{
for (int y = margin.Top; y < bmp.Height - margin.Bottom; y += factorY)
{
if (Tolerance(bmp.GetPixel(x2, y), background) > tolerance)
{
finish = true;
break;
}
}
}
finish = false;
for (y1 = margin.Top; (y1 < bmp.Height - margin.Bottom) && (finish == false); y1++)
{
for (int x = margin.Left; x < bmp.Width - margin.Right; x += factorX)
{
if (Tolerance(bmp.GetPixel(x, y1), background) > tolerance)
{
finish = true;
break;
}
}
}
finish = false;
for (y2 = bmp.Height - margin.Bottom; (y2 > margin.Top) && (finish == false); y2--)
{
for (int x = margin.Left; x < bmp.Width - margin.Right; x += factorX)
{
if (Tolerance(bmp.GetPixel(x, y2), background) > tolerance)
{
finish = true;
break;
}
}
}
var rect = new Rectangle(x1 - 1, y1 - 1, x2 - x1 + 3, y2 - y1 + 3);
var newBmp = new Bitmap(rect.Width, rect.Height);
using (var g = Graphics.FromImage(newBmp))
{
g.DrawImage(bmp, new Rectangle(0, 0, rect.Width, rect.Height), rect, GraphicsUnit.Pixel);
}
return newBmp;
}
private double Tolerance(Color a, Color b)
{
return Math.Sqrt(Math.Min(Math.Pow((int)a.R - b.R, 2) + Math.Pow((int)a.G - b.G, 2) + Math.Pow((int)a.B - b.B, 2), 65025.0)) / 255.0;
}
var img = [B][COLOR="#0000FF"]CropImage[/COLOR][/B](image, Color.White, new Padding(20, 20, 20, 20), 0.1);
عرض سلام و ادبصد البته، اگر منظورتون با زبان #C ئه با چند تا حلقه می توانید...
عرض سلام و ادب
جناب the_king واقعا ازتون ممنونم، کدی که دادید فوق العادست.
من سایت های زیادی (stackoverflow, codeproject, msdn,...) رو گشتم اما بهترین پاسخ رو از شما گرفتم.
چند تا سوال داشتم از خدمتتون...
من یه عکس رو که خروجی یک اسکنر متوسط بود، به این برنامه دادم و در نهایت تونستم با tolerance = 0.3 به نتیجه مطلوب برسم. اما مساله اینه که میخوام پس از تحویل برنامه به مشتری، در صورت تعویض اسکنر، برنامه به مشکل نخوره. یعنی اگر اسکنر جدید ضعیف تر از اسکنر قبلی بود و عکس هاش نویزهای بیشتری داشتن برنامه درست کار کنه. حالا با توجه به وضعیت اسکنرهای موجود در ایران و اینکه این برنامه قراره فقط کارت شناسایی (کارت ملی، شناسنامه،..) رو اسکن بکنه، بهترین tolerance از نظر شما چیه ؟
در ضمن زمانی که Padding.Empty رو به عنوان margin به برنامه میدم ارور زیر رو نشون میده ولی با new Padding(20, 20, 20, 20) جواب میگیرم. مشکل از کجاست ؟
خیلی ممنونم
for (x2 = bmp.Width - margin.Right [B][COLOR="#0000FF"][SIZE=3]- 1[/SIZE][/COLOR][/B]; (x2 >[B][COLOR="#0000FF"][SIZE=3]=[/SIZE][/COLOR][/B] margin.Left) && (finish == false); x2--)
for (y2 = bmp.Height - margin.Bottom [B][COLOR="#0000FF"][SIZE=3]- 1[/SIZE][/COLOR][/B]; (y2 >[B][COLOR="#0000FF"][SIZE=3]=[/SIZE][/COLOR][/B] margin.Top) && (finish == false); y2--)