为了提高我的成像知识并获得一些使用这些主题的经验,我决定在Android平台上创建一个车牌识别算法 .
第一步是检测,我决定实施最近的一篇名为"A Robust and Efficient Approach to License Plate Detection"的论文 . 本文非常好地介绍了他们的想法,并使用非常简单的技术来实现检测 . 除了论文中缺少的一些细节之外,我还实现了双线性下采样,转换为灰度,以及第3A,3B.1和3B.2节中描述的边缘自适应阈值处理 . 不幸的是,我没有得到本文提出的输出,例如:图3和6 .
我用于测试的图像如下:
灰度(和缩减采样)版本看起来很好(参见本文底部的实际实现),我使用了一个众所周知的RGB组件组合来制作它(纸张没有提到如何,所以我猜了) .
接下来是使用概述的Sobel滤波器进行初始边缘检测 . 这产生的图像类似于本文图6中所示的图像 .
最后,删除"weak edges"他们使用20x20窗口应用自适应阈值 . 这是事情的发展方向 wrong .
正如您所看到的,即使我使用其声明的参数值,它也无法正常工作 . 另外我试过:
-
更改beta参数 .
-
使用2d int数组而不是Bitmap对象来简化创建积分图像 .
-
尝试更高的Gamma参数,以便初始边缘检测允许更多"edges" .
-
将窗口更改为例如10×10 .
然而,这些变化都没有改善;它不断产生如上图所示的图像 . 我的问题是:我做的与文章中概述的有何不同?以及如何获得所需的输出?
代码
我使用的(清理过的)代码:
public int[][] toGrayscale(Bitmap bmpOriginal) {
int width = bmpOriginal.getWidth();
int height = bmpOriginal.getHeight();
// color information
int A, R, G, B;
int pixel;
int[][] greys = new int[width][height];
// scan through all pixels
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
// get pixel color
pixel = bmpOriginal.getPixel(x, y);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
int gray = (int) (0.2989 * R + 0.5870 * G + 0.1140 * B);
greys[x][y] = gray;
}
}
return greys;
}
边缘检测代码:
private int[][] detectEges(int[][] detectionBitmap) {
int width = detectionBitmap.length;
int height = detectionBitmap[0].length;
int[][] edges = new int[width][height];
// Loop over all pixels in the bitmap
int c1 = 0;
int c2 = 0;
for (int y = 0; y < height; y++) {
for (int x = 2; x < width -2; x++) {
// Calculate d0 for each pixel
int p0 = detectionBitmap[x][y];
int p1 = detectionBitmap[x-1][y];
int p2 = detectionBitmap[x+1][y];
int p3 = detectionBitmap[x-2][y];
int p4 = detectionBitmap[x+2][y];
int d0 = Math.abs(p1 + p2 - 2*p0) + Math.abs(p3 + p4 - 2*p0);
if(d0 >= Gamma) {
c1++;
edges[x][y] = Gamma;
} else {
c2++;
edges[x][y] = d0;
}
}
}
return edges;
}
自适应阈值处理的代码 . SAT实现取自here:
private int[][] AdaptiveThreshold(int[][] detectionBitmap) {
// Create the integral image
processSummedAreaTable(detectionBitmap);
int width = detectionBitmap.length;
int height = detectionBitmap[0].length;
int[][] binaryImage = new int[width][height];
int white = 0;
int black = 0;
int h_w = 20; // The window size
int half = h_w/2;
// Loop over all pixels in the bitmap
for (int y = half; y < height - half; y++) {
for (int x = half; x < width - half; x++) {
// Calculate d0 for each pixel
int sum = 0;
for(int k = -half; k < half - 1; k++) {
for (int j = -half; j < half - 1; j++) {
sum += detectionBitmap[x + k][y + j];
}
}
if(detectionBitmap[x][y] >= (sum / (h_w * h_w)) * Beta) {
binaryImage[x][y] = 255;
white++;
} else {
binaryImage[x][y] = 0;
black++;
}
}
}
return binaryImage;
}
/**
* Process given matrix into its summed area table (in-place)
* O(MN) time, O(1) space
* @param matrix source matrix
*/
private void processSummedAreaTable(int[][] matrix) {
int rowSize = matrix.length;
int colSize = matrix[0].length;
for (int i=0; i<rowSize; i++) {
for (int j=0; j<colSize; j++) {
matrix[i][j] = getVal(i, j, matrix);
}
}
}
/**
* Helper method for processSummedAreaTable
* @param row current row number
* @param col current column number
* @param matrix source matrix
* @return sub-matrix sum
*/
private int getVal (int row, int col, int[][] matrix) {
int leftSum; // sub matrix sum of left matrix
int topSum; // sub matrix sum of top matrix
int topLeftSum; // sub matrix sum of top left matrix
int curr = matrix[row][col]; // current cell value
/* top left value is itself */
if (row == 0 && col == 0) {
return curr;
}
/* top row */
else if (row == 0) {
leftSum = matrix[row][col - 1];
return curr + leftSum;
}
/* left-most column */
if (col == 0) {
topSum = matrix[row - 1][col];
return curr + topSum;
}
else {
leftSum = matrix[row][col - 1];
topSum = matrix[row - 1][col];
topLeftSum = matrix[row - 1][col - 1]; // overlap between leftSum and topSum
return curr + leftSum + topSum - topLeftSum;
}
}
1 回答
Marvin提供了查找文本区域的方法 . 也许它可以成为你的起点:
Find Text Regions in Images: http://marvinproject.sourceforge.net/en/examples/findTextRegions.html
这个方法也用在这个问题中:
How do I separates text region from image in java
使用你的图像我得到了这个输出:
Source Code: