【发布时间】:2015-03-29 15:20:16
【问题描述】:
我正在尝试实现Anil Jain et al提出的广泛使用的指纹图像增强算法。在实现 2.5 节中脊频率图像计算的步骤时,我有一些描述难以理解。步骤描述如下:
- 获取归一化图像 G。
- 将 G 分成大小为 w x w (16 x 16) 的块。
- 对于以像素 (i, j) 为中心的每个块,计算在脊坐标系中定义的大小为 l x w (32x16) 的定向窗口。
- 对于以像素 (i,j) 为中心的每个块,计算定向内的脊和谷的 x 签名 X[0]、X1、...、X[l-1]窗口,在哪里
如果定向窗口中没有出现细节和奇异点,则x-签名形成离散的正弦波形,其频率与定向窗口中的脊和谷的频率相同。因此,可以从 x 特征估计脊和谷的频率。令 T(i,j) 为 x 签名中两个连续峰值之间的平均像素数,则频率计算为:
我的问题是: 我不明白如何获得两个连续峰值之间的平均像素数,因为论文没有提到如何在算法中区分峰值。那么,如何确定那些峰值像素来计算它们呢?有人可以解释一下我在这里错过了什么吗?
此外,我像这样使用 OpenCV 实现了到目前为止的步骤,如果有人可以通过我的步骤帮助我仔细检查我是否正确实施,我将不胜感激:
void Enhancement::frequency(cv::Mat inputImage, cv::Mat orientationMat)
{
int blockSize = 16;
int windowSize = 32;
//compute x-signature
for (int i = blockSize / 2; i < inputImage.rows - blockSize / 2; i += blockSize)
{
for (int j = blockSize / 2; j < inputImage.cols - blockSize / 2; j += blockSize)
{
int u = 0;
int v = 0;
std::vector<float> xSignature;
for (int k = 0; k < windowSize; k++)
{
float sum = 0.0;
for (int d = 0; d < blockSize; d++)
{
float pixel = orientationMat.at<float>(i, j);
u = i + (d - 0.5 * blockSize) * cos(pixel) + (k - 0.5 * windowSize) * sin(pixel);
v = j + (d - 0.5 * blockSize) * sin(pixel) + (0.5 - windowSize) * cos(pixel);
sum += static_cast<float>(inputImage.at<uchar>(u, v));
}
xSignature.push_back(sum);
}
} // end of j-loop
} // end of i-loop
}
更新
在搜索了一些文章后,我发现有人提到如何确定峰值像素是否像这样:
- 对每个块执行灰度膨胀
- 查找膨胀等于原始值的位置
但是,我还是没看清楚。这是否意味着我可以在我的灰度图像上使用逐块形态膨胀操作(在进一步处理之前,我已经在 OpenCV 中将我的图像从 RGB 转换为灰度)?
dilation equals original values 这个词的意思是 the pixel intensity after morphological dilation equals its original value 吗?我在这里迷路了。
【问题讨论】:
-
这种情况下的峰值是一个窗口方向的局部最大值/最小值,不是吗?
-
所以你的意思是 xSignature 应该有 32 个峰值,因为签名长度是 32,我应该计算两个窗口峰值之间的元素数?
-
嘿@E_learner,我现在在做同样的项目,你知道了吗,我知道已经有 5 年了,但我真的需要知道我的项目,因为我的项目大部分是 -1频率矩阵,只有几个有意义的值。如果你能帮忙请回复,我需要你的帮助>
-
@VaibhavRajput:看看这里,他的实现提供了所有需要的信息:github.com/Ekberjan/Fingerprint_Image_Enhancement
标签: c++ image algorithm opencv image-processing