Building a License Plate Recognition Engine in C++ — Part 2: Grayscale Image Preprocessing and Local Contrast Edge Detection

Building a License Plate Recognition Engine in C++ — Part 2: Grayscale Image Preprocessing and Local Contrast Edge Detection

In the previous article, we loaded an image, converted it into grayscale, and introduced the core data structures used by the recognition engine. In this part, we begin building the preprocessing stage of the LPR pipeline. The goal of preprocessing is to enhance image regions that are likely to contain license plate characters. We will implement: Integral image generation Local contrast analysis Edge map extraction Ternary edge image conversion These operations are designed for high-speed processing and are suitable for real-time systems. Why preprocessing matters in LPR License plates typically contain: High-contrast characters Dense vertical and horizontal transitions Repetitive edge structures Instead of applying expensive operations across the entire image, preprocessing helps emphasize candidate regions before plate detection begins. The pipeline implemented in this article focuses on local intensity differences. Integral Image The first optimization step is building an integral image. An integral image allows us to compute the sum of any rectangular region in constant time. Without an integral image: Region Sum = O(width × height) Enter fullscreen mode Exit fullscreen mode With an integral image: Region Sum = O(1) Enter fullscreen mode Exit fullscreen mode This becomes extremely important when processing every pixel in large images. Computing the integral image void CImageProc::ComputeIntegralImage( unsigned char* pbGray, int nWidth, int nHeight, int* pnSum) { int nW = nWidth + 1; int nH = nHeight + 1; int partialsum; memset(pnSum, 0, nH * nW * sizeof(int)); for (int y = 1; y = nWidth) x1 = nWidth - 1; if (y1 >= nHeight) y1 = nHeight - 1; for (int y = y0; y = nWidth) right = nWidth - 1; if (bottom >= nHeight) bottom = nHeight - 1; int surroundCount = (right - left + 1) * (bottom - top + 1); int surroundSum = pnSum[(bottom + 1) * nW + (right + 1)] - pnSum[top * nW + (right + 1)] - pnSum[(bottom + 1) * nW + left] + pnSum[top * nW + left]; int centerSum = 0; int centerCount = 0; // Center pixel centerSum += pbGray[row + x]; surroundSum -= pbGray[row + x]; centerCount++; surroundCount--; // Left if (x - 1 >= 0) { centerSum += pbGray[row + (x - 1)]; surroundSum -= pbGray[row + (x - 1)]; centerCount++; surroundCount--; } // Right if (x + 1 = 0) { centerSum += pbGray[(y - 1) * nWidth + x]; surroundSum -= pbGray[(y - 1) * nWidth + x]; centerCount++; surroundCount--; } // Bottom if (y + 1 < nHeight) { centerSum += pbGray[(y + 1) * nWidth + x]; surroundSum -= pbGray[(y + 1) * nWidth + x]; centerCount++; surroundCount--; } if (centerCount == 0 || surroundCount <= 0) { lpOut[row + x] = 0; continue; } double centerAvg = (double)centerSum / centerCount; double surroundAvg = (double)surroundSum / surroundCount; lpOut[row + x] = (int)(surroundAvg - centerAvg); } } } Enter fullscreen mode Exit fullscreen mode The algorithm performs: Local neighborhood extraction Center intensity averaging Surrounding intensity averaging Difference calculation Result: Strong intensity transitions ↓ High edge responses Enter fullscreen mode Exit fullscreen mode This is particularly effective for license plate characters because they contain strong contrast boundaries. Current preprocessing pipeline Our LPR engine now performs: Input Image ↓ Grayscale Conversion ↓ Integral Image ↓ Local Contrast Analysis ↓ Edge Map Generation ↓ Ternary Edge Image Enter fullscreen mode Exit fullscreen mode At this point, the engine can already highlight regions containing dense character-like structures. In the next article, we will begin locating candidate license plate regions using the generated edge information.

Original Source

Read the full article at Dev →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.