Co to jest „deskew” (i dlaczego ma to znaczenie)

Skew występuje, gdy dokument jest skanowany lub fotografowany w lekkim kącie (zwykle ±0–5°). Wynik: linie tekstowe nie są horyzontalne, krawędzi pionowe są wciśnięte, a obraz ma subtelną rotację. Dzkiew jest procesem wykrywanie kąta skręcania i odwrócenie obrazu z powrotem W ten sposób linie stają się ponownie horyzontalne / pionowe.

Jak skrzydła boli twój rurociąg

  • **Wskaźnik dokładności OCR: **Tylated baselines przeszkadza segmentacji, znalezienia linii i klasyfikacji znaków; małe kąty mogą dramatycznie zmniejszyć dokładność.
  • Barcody nie decodują: Wiele symbologii liniowych (np. Kod 128/39) jest wrażliwe na rotację; nadmierne skurcze zmniejszają udane odczyty.
  • Przełamanie i rozmieszczenie wykrywania przerwy: odkrywanie krawędzi strony i wykrywka linii tabeli często przyjmuje geometrii prawie prawogonalnej.

Jak Aspose.Imaging naprawi skw – dokładnie

Aspose.Imaging eksponuje one-call deskew na obrazach rasterowych:

  • RasterImage.NormalizeAngle() - automatycznie wykrywa kąt skierowania (używa wewnętrznie GetSkewAnglei obrazy obrazu w miejscu.
  • Nadmierne obciążenie : NormalizeAngle(bool resizeProportionally, Color backgroundColor) — wybierz, czy rozszerzyć przewód, aby zachować całą zawartość i który ** kolor tła** wypełnia kąty utworzone przez rotację.

Istnieją również koledzy Cloud & UI (REST i narzędzie online), które wykazują tę samą operację, jeśli budujesz usługi lub prototypy.

Pełny przykład (copy paste)

Ten przykład pokazuje bezpieczne wstępne przetwarzanie i wytrzymałe odkurzanie z Aspose.Imaging:

  • Pobierz skanowanie (JPG / PNG / TIFF)
  • Opcjonalnie przekształca się w grayscale i normalizuje kontrast dla lepszego wykrywania kąta.
  • Calls NormalizeAngle(resizeProportionally: true, background: White).
  • Oszczędza wstrząśnięty obraz.
  • Bonus: pokazuje, jak wyłączyć każdą stronę w multi-page TIFF.
  • Wymagania *
  • .NET 8 (lub 6+)
  • W Nowym Jorku: Aspose.Imaging

using System;
using System.IO;
using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Tiff;
using Aspose.Imaging.ImageOptions;

class Program
{
    static int Main(string[] args)
    {
        if (args.Length < 2)
        {
            Console.WriteLine("Usage: dotnet run -- <inputImageOrTiff> <outputImageOrTiff>");
            return 1;
        }

        string inputPath  = args[0];
        string outputPath = args[1];

        try
        {
            using (var image = Image.Load(inputPath))
            {
                // Multi-page TIFF? Deskew frame-by-frame.
                if (image is TiffImage tiff)
                {
                    foreach (var frame in tiff.Frames)
                    {
                        // --- Optional: lightweight preprocessing for better angle detection ---
                        // Convert to grayscale-like statistics to reduce chroma noise.
                        // Many real scans already are gray/bilevel; if not, Normalize() helps.
                        TryNormalizeForDeskew(frame);

                        // --- Deskew ---
                        // true  = expand canvas to avoid cropping
                        // White = fill color for the new corners created by rotation
                        frame.NormalizeAngle(true, Aspose.Imaging.Color.White);
                    }

                    tiff.Save(outputPath); // encoder inferred from extension
                }
                else
                {
                    // Single-page raster image
                    var raster = image as RasterImage 
                                 ?? throw new InvalidOperationException("Input is not a raster image.");

                    TryNormalizeForDeskew(raster);
                    raster.NormalizeAngle(true, Aspose.Imaging.Color.White);

                    // Choose encoder explicitly (e.g., PNG/JPEG/TIFF). Here we mirror input extension.
                    image.Save(outputPath);
                }
            }

            Console.WriteLine($"✅ Deskew complete: {Path.GetFullPath(outputPath)}");
            return 0;
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine("❌ " + ex.Message);
            return 2;
        }
    }

    /// <summary>
    /// Minimal, safe preprocessing to stabilize skew detection.
    /// Avoid heavy blurs that can smear thin text.
    /// </summary>
    private static void TryNormalizeForDeskew(RasterImage raster)
    {
        // Ensure pixels are accessible (performance hint for subsequent operations).
        raster.CacheData();

        // If the image has wildly varying brightness (camera shots), a light contrast
        // normalization can help align text lines for skew detection. The exact set
        // of helpers varies by version; keep it simple and non-destructive.
        //
        // Tip: If your version exposes BinarizeOtsu/AdaptiveBinarize, try them
        // *after* deskew for OCR workflows to preserve thin strokes.

        // Example: If available in your build, uncomment one of these:
        // raster.AdjustBrightnessContrast(brightness: 0, contrast: 10); // gentle contrast pop
        // raster.Grayscale(); // reduce chroma noise if present

        // Leave as-is if your scans are already clean (e.g., 300 dpi monochrome).
    }
}

Why NormalizeAngle Działa dobrze

  • Odkrywa **kąt skręcania dla typowego skanowanego tekstu (używając statystyk bazowych/edge) i rotates w jednym wezwaniu.
  • W tym resizeProportionally Opcja uniemożliwia korner clipping, a backgroundColor Parametry kontrolują kolor nowo wystawionych obszarów.

Multi-page TIFF deskew (co oglądać)

  • Run NormalizeAngle * na ramy *; TiffFrame Jest to strona raster, więc stosuje się tę samą API.
  • Oszczędzaj raz na końcu; rozważ kompresję ** bez strat** (np. LZW/Deflate dla RGB, CCITT Group 4 dla bilevel).
  • Jeśli planujesz OCR później, trzymaj strony w 300 dpi (lub wyżej), aby zachować małe glify.

Zwyczajne pęcherzyki - i jak je unikać

  • Kropienie po rotacjiJeśli rotujesz bez rozszerzenia kanapy, kąty zostaną wycięte. NormalizeAngle(true, Color.White) Zrób to proporcjonalnie *.

  • ** Brudne tło kłóci detektor kąta**Ciężki hałas lub gradienty mogą zniechęcać do szacunku kąta. wykonaj normalizację światła (twarz kontrastu lub grayscale) przed wykończeniem, ale unikać silnych blurów, które usuwają cienkie wstrząsy.

    • nadmierna binaryzacja*Ciężkie granice mogą tworzyć zakrzywione baseliny; najpierw rozdrabnij, a następnie binaryzuj dla OCR, jeśli to konieczne. (przewodnik OCR podkreśla wczesną korektę skierowania w rurociągu.)
    • skanowanie kodów barkódowych w ścisłych kątach*Jeśli kody barowe wciąż nie spełniają po wyłączeniu, sprawdź, że kąt nie jest nasycony; bardzo gęste strzały mogą wymagać pierwotnego obrotu/flip przez metadane (EXIF) przed NormalizeAngle.

FAQs

** Q: Czy deskew zmienia rozmiar obrazu?**A: Jeśli przejdziesz resizeProportionally: true, kanwy rosną wystarczająco dużo, aby utrzymać całą zawartość - nie gromadzić - wypełniając nowe rogi z wybraną kolorem.

Q: Czy mogę najpierw wykryć kąty?**A: Deskew jest zwykle jednym strzałem z NormalizeAngle, ale jeśli potrzebujesz kątów do analizy, można mierzyć za pomocą powiązanych API (np. produkty OCR narażają obliczenie kąta).

** Q: Co z Cloud / REST?**A: Aspose.Imaging Cloud wyświetla deskew Koniec, jeśli budujesz usługę zamiast korzystać z biblioteki .NET.

Takeaways

  • Skew cierpi na OCR, czytanie kodów barowych i analizę układu.
  • Aspose.Imaging’s RasterImage.NormalizeAngle daje szybkie, niezawodne rozwiązanie z jednym wezwaniem, a także opcje ochrony granic zawartości.
  • Połączyć gentle preprocessing (opcjonalnie) z per-page deskew dla wielu stron TIFF w celu maksymalizacji dokładności.

Dzięki tym praktykom aplikacje .NET będą wytwarzać szybsze, bardziej czytelne skanowanie – a poniższe etapy OCR i kodów rzęs podziękować.

More in this category