20251014 保存 DenseOpticalFlow 为 PPM 图片

保存 DenseOpticalFlow 为 PPM 图片

std::string leftPadZeros(const std::string &str, int totalWidth)
{
    if (str.length() >= totalWidth)
    {
        return str;  // 如果原字符串已经足够长,直接返回
    }
    return std::string(totalWidth - str.length(), '0') + str;
}

#define PI_VAL 3.1415926535897932384626433832795
#define MAX(a, b)  ((a) < (b) ? (b) : (a))
#define MIN(a, b)  ((a) > (b) ? (b) : (a))
#define ABS(a)     ((a) < 0 ? -(a) : (a))

namespace fs = std::filesystem;

struct Pointf {
    float x, y;
};

struct HSV2RGB {
    typedef float channel_type;

    HSV2RGB(int _dstcn, int _blueIdx, float _hrange)
            : dstcn(_dstcn), blueIdx(_blueIdx), hscale(6.f / _hrange)
    {}

    void operator()(const float *src, float *dst, int n) const
    {
        int   i, bidx = blueIdx, dcn = dstcn;
        float _hscale = hscale;
        float alpha   = 1.0f;
        n *= 3;

        for (i = 0; i < n; i += 3, dst += dcn)
        {
            float h = src[i], s = src[i + 1], v = src[i + 2];
            float b, g, r;

            if (s == 0)
                b = g = r = v;
            else
            {
                static const int sector_data[][3] =
                                         {{1, 3, 0},
                                          {1, 0, 2},
                                          {3, 0, 1},
                                          {0, 2, 1},
                                          {0, 1, 3},
                                          {2, 1, 0}};

                float tab[4];
                int   sector;

                h *= _hscale;
                if (h < 0.0f)
                {
                    do h += 6; while (h < 0.0f);
                } else if (h >= 6.0f)
                    do h -= 6; while (h >= 6.0f);

                if (ABS(h - 6) < 0.000001)
                    h  = 0;
                sector = floorf(h);

                h -= sector;

                tab[0] = v;
                tab[1] = v * (1.f - s);
                tab[2] = v * (1.f - s * h);
                tab[3] = v * (1.f - s * (1.f - h));
                b = tab[sector_data[sector][0]];
                g = tab[sector_data[sector][1]];
                r = tab[sector_data[sector][2]];
            }

            dst[bidx]     = b;
            dst[1]        = g;
            dst[bidx ^ 2] = r;
            if (dcn == 4)
                dst[3]    = alpha;
        }
    }

    int   dstcn, blueIdx;
    float hscale;
};


void saveFlowAsPPM(const std::string &dumpPath, Pointf *denseFlow, size_t width, size_t height)
{
    // PPM is an image format, can open with default image viewer on ubuntu.
    std::string flow_ppm_filename = dumpPath + ".ppm";

    create_path(flow_ppm_filename);

    FILE *pOutFile = NULL;
    pOutFile = fopen(flow_ppm_filename.c_str(), "wb");

    fprintf(pOutFile, "P6\n");
    fprintf(pOutFile, "%ld %ld\n", (long) width, (long) height);
    fprintf(pOutFile, "255\n");

    HSV2RGB cvt(0, 0, 360);

    size_t size = height * width;

    int max_flow = 128 / 2;

    for (size_t i = 0; i < size; i++)
    {
        double uD  = denseFlow[i].x;
        double vD  = denseFlow[i].y;
        double mag = (double) sqrt((uD * uD) + (vD * vD));
        double dir = (double) atan2(vD, uD);
        double H, S, V;
        H = fmod((dir / (2.0 * PI_VAL)), 1) * 360;
        //8 is changed to 16
        S = mag * 8 / max_flow;
        V = 8 - S;
        S = MIN(MAX(S, 0), 1);
        V = MIN(MAX(V, 0), 1);

        float HSV[3] = {(float) H, (float) S, (float) V};
        float RGB[3];

        cvt(HSV, RGB, 1);

        uint8_t R, G, B;
        R = (uint8_t) (RGB[2] * 255.f);
        G = (uint8_t) (RGB[1] * 255.f);
        B = (uint8_t) (RGB[0] * 255.f);

        fputc(R, pOutFile);
        fputc(G, pOutFile);
        fputc(B, pOutFile);
    }
    fclose(pOutFile);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值