cjh3020889729 / The-PaddleX-QT-Visualize-GUI

The-PaddleX-QT-Visualize-GUI
Apache License 2.0
38 stars 15 forks source link

color_list的声明在不同平台上可能导致不同值 #2

Closed geoexploring closed 2 years ago

geoexploring commented 2 years ago

https://github.com/cjh3020889729/The-PaddleX-QT-Visualize-GUI/blob/e00f798757614e886b5da341b517fb4e71aa2e3b/deploy/cpp/docs/jetson_deploy/qt_demo/infer_thread.cpp#L29 这行代码存在于原始代码中的如下函数:

void InferThread::get_color_map_list(int num_classes)
{
    uchar *color_list = new uchar[num_classes * 3];
    num_classes += 1;
    for (int i = 1; i < num_classes; i++)
    {
        int j = 0;
        int lab = i;
        while (lab != 0)
        {
            color_list[(i-1) * 3] |= (uchar)(((lab >> 0) & 1)
                                             << (7 - j));
            color_list[(i-1) * 3 + 1] |= (uchar)(((lab >> 1) & 1)
                                                 << (7 - j));
            color_list[(i-1) * 3 + 2] |= (uchar)(((lab >> 2) & 1)
                                                 << (7 - j));

            j += 1;
            lab >>= 3;
        }
    }
    color_map_ = color_list;
}

这个函数对应paddleseg中的https://github.com/PaddlePaddle/PaddleSeg/blob/8a9196177c9e4b0187f90cbc6a6bc38a652eba73/tools/gray2pseudo_color.py#L37,即:

def get_color_map_list(num_classes):
    """
    Returns the color map for visualizing the segmentation mask,
    which can support arbitrary number of classes.
    Args:
        num_classes (int): Number of classes.
    Returns:
        (list). The color map.
    """

    num_classes += 1
    color_map = num_classes * [0, 0, 0]
    for i in range(0, num_classes):
        j = 0
        lab = i
        while lab:
            color_map[i * 3] |= (((lab >> 0) & 1) << (7 - j))
            color_map[i * 3 + 1] |= (((lab >> 1) & 1) << (7 - j))
            color_map[i * 3 + 2] |= (((lab >> 2) & 1) << (7 - j))
            j += 1
            lab >>= 3
    color_map = color_map[3:]
    return color_map

我发现由于后续代码中的位运算操作,color_list初始值的不同,最终的值也不同,不仅python结果和qt(MinGW64)不同,qt(MinGW64)和vs(msvc2017 64)也不同,尤其是在vs(msvc2017 64)中会导致最终可视化出现问题。

当我修改了color_list在C++ 代码中的声明,即在uchar *color_list = new uchar[num_classes * 3];后增加memset(color_list, 0, num_classes * 3);,vs(msvc2017 64)中的可视化恢复正常。但是color_list 的最终结果(均值和方差)在python、qt(MinGW64)、vs(msvc2017 64)也不完全相同(很接近),这可能是后续的位运算导致的。

以上是我的理解,请问有没有错呢?

谢谢

cjh3020889729 commented 2 years ago

我认为应该是位运算所导致的。如果你确定了类别数,建议直接设定一个类似枚举一样的color_list返回即可。当然如果你确实需要确定通过位操作实现的话,可能需要确定不同环境下数据类型对应的位数——比如系统环境或者编译器。 这部分的cpp的color_list生成是来自于paddlex的seg部署。

geoexploring commented 2 years ago

@cjh3020889729 , 谢谢!