【问题标题】:How to understand the average pixel number described in the frequency image?如何理解频率图像中描述的平均像素数?
【发布时间】:2015-03-29 15:20:16
【问题描述】:

我正在尝试实现Anil Jain et al提出的广泛使用的指纹图像增强算法。在实现 2.5 节中脊频率图像计算的步骤时,我有一些描述难以理解。步骤描述如下:

  1. 获取归一化图像 G。
  2. 将 G 分成大小为 w x w (16 x 16) 的块。
  3. 对于以像素 (i, j) 为中心的每个块,计算在脊坐标系中定义的大小为 l x w (32x16) 的定向窗口。
  4. 对于以像素 (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

}

更新

在搜索了一些文章后,我发现有人提到如何确定峰值像素是否像这样:

  1. 对每个块执行灰度膨胀
  2. 查找膨胀等于原始值的位置

但是,我还是没看清楚。这是否意味着我可以在我的灰度图像上使用逐块形态膨胀操作(在进一步处理之前,我已经在 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


【解决方案1】:

我不知道你说的具体算法,但也许我可以提供一些一般性的建议。

我想问题的核心是噪声信号中“什么是峰值,什么只是噪声”的区别(因为 RL 输入图像在某种意义上总是有噪声的;我认为用于峰值检测的相关输入向量在您的代码是 xSignature)。确定峰值后,计算平均峰值距离应该相当简单。

关于峰值检测,有大量论文描述了相当复杂的算法,但我将概述一些我在图像处理工作中使用的经过验证的真实方法。

平滑

如果您知道预期峰宽w,您可以作为第一步应用一些平滑处理,通过在大约预期峰宽 (从 x-w/2 到 x+w/2)。您实际上不需要计算滑动窗口的平均值(除以 w),因为对于峰值检测,绝对比例无关紧要,总和与平均值成正比。

最小-最大-识别

您可以遍历(可能平滑的)轮廓矢量并识别最小和最大索引(例如通过简单的斜率符号更改)。将这些位置存储在map&lt;int (coordinate), bool (isMax)&gt;map&lt;int (coordinate), double (value at coordinate)&gt; 中。或者使用一个结构作为包含所有相关信息的值(bool isMax,double value,bool isAtBoundary,...)

评估检测峰的质量

对于您在上一步中找到的每个最大值,确定高度差,并可能确定前一个和下一个最小值的斜率,从而产生一个质量。此步骤取决于您的问题域。也许“峰值”不需要两边都用最小值框定(在这种情况下,上面的最小检测必须比斜率变化更复杂)。也许对峰有最小或最大宽度限制。以此类推。

根据上述问题计算每个最大位置的质量值。我经常使用 Q_max =(从最大值到相邻分钟的平均高度差)/(轮廓的最大最小值)之类的东西。一个峰值候选者的“质量”最多为 1,至少为 0。

遍历所有最大值,计算它们的质量并将它们放入多图或其他容器中,这些容器可以排序,以便您以后可以以递减的质量遍历峰值。

区分峰值和非峰值

以递减的质量迭代您的峰值。可能整理出所有不满足最小或最大宽度/高度/质量/到最近峰值的距离更高质量/...要求它们成为您的问题域中的峰值的所有内容。保留其余部分。完成。

在您的情况下,您将通过坐标重新排列峰值并计算它们之间的平均距离。

我知道这很模糊,但是对于峰值检测没有普遍正确的答案。也许在您正在使用的论文中,某个地方隐藏了一个特定的处方,但大多数作者都忽略了这种“纯粹的技术性”(通常,如果您通过电子邮件与他们联系,他们不记得或以其他方式重现他们是如何做到的,这使得他们的结果基本上无法重现)。

【讨论】:

  • 感谢您的回答。我使用的算法在我的问题中有所描述,尤其是我提到的论文。
  • 我不能花时间为你做研究(即阅读和理解科学论文)。我对图像处理算法中的任何 RL 输入数据的看法是,指纹脊线图像不会沿着垂直于脊线的方向形成数学上完美的“正弦形状”,而是接近它的东西。您必须进行一些噪声消除/模糊峰值检测来识别“脊峰”,然后测量它们之间的距离,这就是为什么我给出了一些关于如何做到这一点的指示。
  • 好的,再次感谢您。我将尝试实施您当时建议的方法。不过在接受你的回答之前,我也会等着看别人有没有其他想法。
  • 可以在平滑之后,用DFT估计频率而不取直流分量吗?
  • 如果从 (x - delta) 到 (x + delta) 进行对称平滑,峰的位置不会改变(并且它们之间的距离应该保持不变,无论平滑窗口选择如何) ,因此 DFT 应该产生一个可用的频率结果。
猜你喜欢
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
  • 1970-01-01
相关资源
最近更新 更多