Tôi đã tìm kiếm cao và thấp cho một cách đáng tin cậy để xóa một hình ảnh trong. Net, và không có nhiều may mắn.Sử dụng .Net để xóa một hình ảnh
Vào phút tôi đang sử dụng Aforge. Đây là một nỗi đau khi tôi làm việc với WPF, vì vậy những hình ảnh mà tôi đang làm việc với các đối tượng BitmapImage, trái ngược với các đối tượng Bitmap, có nghĩa là tôi cần bắt đầu với một đối tượng BitmapImage, lưu nó vào một luồng bộ nhớ, tạo một đối tượng Bitmap mới từ luồng bộ nhớ, đi qua quy trình deskewing, lưu hình ảnh đã được xóa vào luồng bộ nhớ mới và sau đó tạo đối tượng BitmapImage mới từ luồng bộ nhớ đã nói. Không chỉ vậy, nhưng deskewing không phải là tuyệt vời.
Tôi đang cố gắng đọc dữ liệu OMR của một mẩu giấy được quét vào máy quét, và do đó tôi cần phải dựa vào một hộp OMR cụ thể ở cùng một tọa độ mỗi lần, do đó deskewing cần phải đáng tin cậy.
Vì vậy, tôi đang sử dụng Aforge vào phút, tôi không thể tìm thấy bất kỳ thư viện mã nguồn mở/miễn phí nào khác cho hình ảnh deskewing trong. Net, mọi thứ tôi đã tìm thấy đều đúng hoặc đắt tiền trong C/C++.
Câu hỏi của tôi là các thư viện nguồn mở/miễn phí khác tồn tại có hỗ trợ trong deskewing hình ảnh trong .Net? Nếu vậy họ được gọi là gì, nếu không làm thế nào tôi nên tiếp cận vấn đề này?
Chỉnh sửa: Ví dụ, giả sử tôi có trang bên dưới:
Lưu ý: Đây là chỉ mang tính chất minh họa, nhưng hình ảnh thực tế không thực sự có một hình chữ nhật màu đen ở mỗi góc của trang, có thể điều này sẽ giúp ích.
Khi tôi in này ra, và quét nó trở lại vào máy quét của tôi, nó trông như thế này:
tôi cần phải deskew hình ảnh này để hộp của tôi là ở cùng một chỗ mỗi lần. Trong thế giới thực, có rất nhiều hộp, chúng nhỏ hơn và gần nhau, vì vậy độ chính xác là quan trọng.
phương pháp hiện tại của tôi cho đây là một đồ sộ không hiệu quả đau-in-the-ass:
using AForge.Imaging;
using AForge.Imaging.Filters;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;
public static BitmapImage DeskewBitmap(BitmapImage skewedBitmap)
{
//Using a memory stream to minimise disk IO
var memoryStream = BitmapImageToMemoryStream(skewedBitmap);
var bitmap = MemoryStreamToBitmap(memoryStream);
var skewAngle = CalculateSkewAngle(bitmap);
//Aforge needs a Bppp indexed image for the deskewing process
var bitmapConvertedToBbppIndexed = ConvertBitmapToBbppIndexed(bitmap);
var rotatedImage = DeskewBitmap(skewAngle, bitmapConvertedToBbppIndexed);
//I need to convert the image back to a non indexed format to put it back into a BitmapImage object
var imageConvertedToNonIndexed = ConvertImageToNonIndexed(rotatedImage);
var imageAsMemoryStream = BitmapToMemoryStream(imageConvertedToNonIndexed);
var memoryStreamAsBitmapImage = MemoryStreamToBitmapImage(imageAsMemoryStream);
return memoryStreamAsBitmapImage;
}
private static Bitmap ConvertImageToNonIndexed(Bitmap rotatedImage)
{
var imageConvertedToNonIndexed = rotatedImage.Clone(
new Rectangle(0, 0, rotatedImage.Width, rotatedImage.Height), PixelFormat.Format32bppArgb);
return imageConvertedToNonIndexed;
}
private static Bitmap DeskewBitmap(double skewAngle, Bitmap bitmapConvertedToBbppIndexed)
{
var rotationFilter = new RotateBilinear(-skewAngle) { FillColor = Color.White };
var rotatedImage = rotationFilter.Apply(bitmapConvertedToBbppIndexed);
return rotatedImage;
}
private static double CalculateSkewAngle(Bitmap bitmapConvertedToBbppIndexed)
{
var documentSkewChecker = new DocumentSkewChecker();
double skewAngle = documentSkewChecker.GetSkewAngle(bitmapConvertedToBbppIndexed);
return skewAngle;
}
private static Bitmap ConvertBitmapToBbppIndexed(Bitmap bitmap)
{
var bitmapConvertedToBbppIndexed = bitmap.Clone(
new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format8bppIndexed);
return bitmapConvertedToBbppIndexed;
}
private static BitmapImage ResizeBitmap(BitmapImage originalBitmap, int desiredWidth, int desiredHeight)
{
var ms = BitmapImageToMemoryStream(originalBitmap);
ms.Position = 0;
var result = new BitmapImage();
result.BeginInit();
result.DecodePixelHeight = desiredHeight;
result.DecodePixelWidth = desiredWidth;
result.StreamSource = ms;
result.CacheOption = BitmapCacheOption.OnLoad;
result.EndInit();
result.Freeze();
return result;
}
private static MemoryStream BitmapImageToMemoryStream(BitmapImage image)
{
var ms = new MemoryStream();
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(ms);
return ms;
}
private static BitmapImage MemoryStreamToBitmapImage(MemoryStream ms)
{
ms.Position = 0;
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
bitmap.Freeze();
return bitmap;
}
private static Bitmap MemoryStreamToBitmap(MemoryStream ms)
{
return new Bitmap(ms);
}
private static MemoryStream BitmapToMemoryStream(Bitmap image)
{
var memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Bmp);
return memoryStream;
}
Nhìn lại, thêm một vài câu hỏi:
- Tôi có sử dụng AForge chính xác?
- Là AForge thư viện tốt nhất để sử dụng cho tác vụ này?
- Cách tiếp cận hiện tại của tôi được cải thiện này để có kết quả chính xác hơn?
Đây là vấn đề khi sử dụng các công cụ xử lý hình ảnh làm hộp đen. Có nhiều cách để giảm bớt, và điều quan trọng là phải biết cách tiếp cận được sử dụng đặc biệt khi nó "không phải là" tuyệt vời ". Nếu không, làm cách nào để bạn biết liệu một hộp đen khác có bất kỳ cơ hội nào để tạo ra kết quả tốt hơn so với hộp đen hiện tại của bạn không? Letponica cũng có một phương pháp khử hộp đen, nhưng tại http://tpgit.github.com/Leptonica/skew_8c.html bạn có thể đọc những gì nó làm. Và có rất nhiều cách khác để đạt được điều này. – mmgp
@mmgp Tôi đồng ý, và tôi ước rằng tôi có thời gian để học các thuật toán biến đổi hough, và C++ nhưng đáng buồn là tôi có thời hạn, vì vậy quyền anh đen là lựa chọn duy nhất của tôi ngay bây giờ! Thankyou cho liên kết, tôi sẽ kiểm tra xem nó ra. – JMK
John, Bạn có thể tạo liên kết đến hình ảnh mà bạn đang gặp sự cố deskewing hoặc đưa chúng vào câu hỏi không? Điều này sẽ giúp mọi người dễ dàng trả lời hơn. – DermFrench