如何理解频率图像中描述的平均像素数?

E_l*_*ner 5 c++ algorithm opencv image image-processing

我正在尝试实现Anil Jain等人提出的广泛使用的指纹图像增强算法.在2.5节中实现脊频图像计算的步骤时,我很难理解某些描述.步骤描述如下:

  1. 获得标准化图像G.
  2. 将G分成大小为wxw(16 x 16)的块.
  3. 对于以像素(i,j)为中心的每个块,计算在脊坐标系中定义的大小为lxw(32×16)的定向窗口.
  4. 对于以像素(i,j)为中心的每个块,计算定向窗口内的脊和谷的x-signature,X [0],X 1,...,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

}
Run Code Online (Sandbox Code Playgroud)

更新

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

  1. 对每个块执行灰度扩张
  2. 找到扩张等于原始值的位置

但是,我仍然没有清楚地理解它.这是否意味着我可以在我的灰度图像上采用逐块形态膨胀操作(在进一步处理之前,我已经在OpenCV中将我的图像从RGB转换为灰度)?这个词dilation equals original values意味着the pixel intensity after morphological dilation equals its original value什么?我迷失在这里.

Dan*_*iel 5

我不知道您正在谈论的具体算法,但也许我可以提供一些一般性的建议.

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

至于峰值检测,有大量的论文描述了相当复杂的算法,但我将概述一些我在图像处理工作中使用的尝试和真实的方法.

平滑

如果您知道预期的峰宽w,您可以作为第一步应用一些平滑,通过在大约预期峰宽(从x- w/2到x + w /)的窗口上求和来消除较小尺度的噪声2).您实际上不需要计算滑动窗口的平均值(除以w),因为对于峰值检测,绝对标度是无关的,并且总和与平均值成比例.

最小 - 最大识别

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

评估检测到的峰的质量

对于您在上一步中找到的每个最大值,确定高度差,可能是前一个和下一个最小值的斜率,从而产生质量.此步骤取决于您的问题域.也许"峰值"不需要用双方的最小值构成(在这种情况下,上面的最小检测必须比斜率变化更复杂).也许峰值有最小或最大宽度限制.等等.

根据每个最大位置的上述问题计算质量值.我经常使用类似Q_max =(从最大值到相邻分钟的平均高度差)/(配置文件的最大最小值).然后,峰值候选者最多可具有1的"质量",并且至少为0.

迭代所有最大值,计算它们的质量并将它们放入多图或其他容器中,这些容器可以进行排序,以便您可以稍后以降序质量迭代峰值.

区分峰与非峰

以降低的质量迭代你的峰值.可能会将所有不满足最小或最大宽度/高度/质量/距离的所有不符合最接近峰值的要求进行整理,以满足您在问题域中达到峰值的更高质量/ ......要求.剩下的就是.完成.

在您的情况下,您将按坐标重新排序峰值并计算它们之间的平均距离.

我知道这很模糊,但峰值检测没有普遍真实的答案.也许在你正在使用的论文中,有一个特定的处方隐藏在某个地方,但大多数作者省略了这些"纯粹的技术性"(通常,如果你通过电子邮件联系他们,他们就无法记住或以其他方式重现他们是如何做到的,这会呈现出来他们的结果基本上不可复制).