为什么我在 C++ 中得到“nan”值?

skm*_*skm 1 c++ opencv

我正在为图像制作相关图。对于每个像素,相关图会在一定的距离 d 范围内找到相同颜色的像素。相关图是一个二维矩阵,即correlogram[color][distance]。相关图的计算与直方图的计算有些相似。

我的代码: 我发布了代码的一些主要部分,其中所有计算都在进行。其余代码(我没有发布)用于满足其他条件,因此不是必需的。

问题:在我的期末考试中correlogram[][],有些值为“nan”。我已经检查了代码,但我无法找到我的计算/语法中的问题所在。

int ColorBins = 180;
int DistanceRange = 5;

double calcCorrelogram(Mat hsvImage)
{
    double correlogram[ColorBins][DistanceRange];
    int pixelNum[ColorBins]; //Used to count the number of pixels of same color

    Mat hsvPlanes[3];
    split(hsvImage, hsvPlanes);

    for(int pi=0; pi<hsvImage.rows; pi++)
    {
        for(int pj=0; pj<hsvImage.cols; pj++)
        {
            int pixelColor = (int)hsvPlanes[0].at<uchar>(pi,pj);
            pixelNum[pixelColor]++; 

            for(int d=1; d<=DistanceRange; d++)
            {
                int sameColorNum=0; //* number of pixels with same color in the d-distance boundary */
                int totalBoundaryNum=0; //* total number of pixels in the d-distance boundary */

                for(int i= pi-d, j= pj-d; j<=pj+d; j++)
                {
                    if(i<0)
                        break;
                    if(j<0 || j>=hsvImage.cols)
                        continue;

                    int neighbourColor  = (int)hsvPlanes[0].at<uchar>(i,j);
                    if(pixelColor == neighbourColor)
                    {
                        sameColorNum++;
                    }
                    totalBoundaryNum++;

                    correlogram[pixelColor][d-1] = correlogram[pixelColor][d-1] + (double)sameColorNum / (double)totalBoundaryNum;
            }   
        } 
    }

    for(int c=0; c<ColorBins; c++)
    {
        for(int d=0; d<DistanceRange; d++)
        {
            if(pixelNum[c] != 0)
                correlogram[c][d] = correlogram[c][d] / (double)pixelNum[c];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Vau*_*ato 5

NaN 通常是在零除以零或零乘以无穷大时创建的。检查 NaN 和无穷大等异常数字的一种简单方法是乘以零并检查结果是否为零:

bool is_valid_double(double x)
{
    return x*0.0==0.0;
}
Run Code Online (Sandbox Code Playgroud)

x如果为 NaN 或无穷大,则返回 false 。

然后,您可以在代码中添加断言,以帮助找到问题所在:

assert(is_valid_double(correlogram[c][d]));
Run Code Online (Sandbox Code Playgroud)

一旦由于断言失败而发生崩溃,您可以使用调试器查看程序的状态,以帮助确定发生了什么。