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

时间:2015-01-30 07:13:08

标签: c++ image algorithm opencv image-processing

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

  1. 获取标准化图像G.
  2. 将G分成大小为w x w(16 x 16)的块。
  3. 对于以像素(i,j)为中心的每个块,计算在脊坐标系中定义的尺寸为l×w(32×16)的定向窗口。
  4. 对于以像素(i,j)为中心的每个块,计算内部脊和谷的x-signature,X [0],X 1,...,X [l-1]面向窗口,其中
  5. enter image description here

    enter image description here

    如果在定向窗口中没有出现细节和奇点,则x特征形成离散的正弦波形,其频率与定向窗口中的脊和谷的频率相同。因此,可以从x-特征估计脊和谷的频率。令T(i,j)为x-签名中两个连续峰值之间的平均像素数,则频率计算如下:

    enter image description here

    我的问题是: 我不明白如何获得两个连续峰值之间的平均像素数,因为本文没有提到如何区分算法中的峰值。那么,如何确定那些峰值像素来计算它们呢?有人能解释一下我在这里想念的是什么吗?

    此外,我使用这样的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. 查找扩张等于原始值的位置
    3. 但是,我仍然没有清楚地理解它。这是否意味着我可以在我的灰度图像上采用逐块形态膨胀操作(在进一步处理之前,我已经在OpenCV中将我的图像从RGB转换为灰度)? 单词dilation equals original values是否意味着the pixel intensity after morphological dilation equals its original value?我迷失在这里。

1 个答案:

答案 0 :(得分:5)

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

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

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

平滑

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

最小 - 最大 - 鉴定

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

评估检测到的峰的质量

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

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

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

区分峰与非峰

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

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

我知道这是模糊的,但是对于峰值检测没有普遍真实的答案。也许在你正在使用的论文中,有一个特定的处方隐藏在某个地方,但大多数作者省略了这些&#34;仅仅是技术性的&#34; (通常情况下,如果您通过电子邮件与他们联系,他们就无法记住或以其他方式重现他们如何做到这一点,这使得他们的结果基本上不可复制)。