首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将C++转换为C#时图像的离散余弦变换结果不同的问题

将C++转换为C#时图像的离散余弦变换结果不同的问题
EN

Stack Overflow用户
提问于 2018-09-19 03:52:43
回答 2查看 119关注 0票数 0

我试着写一个应用程序,对图像片段进行DCT-2变换,然后再用逆DCT-2变换回来。我在c++/opencv中找到了一些我想要转换成C#的代码,但不知何故,我在某些时候得到了不同的结果。下面是我尝试转换的代码:

代码语言:javascript
运行
复制
for (unsigned v = 0; v < BLOCK_SIZE; ++v)
{   
    for (unsigned u = 0; u < BLOCK_SIZE; ++u)
    {   
        const double cu = (u == 0) ? 1.0 / sqrt(2) : 1.0;
        const double cv = (v == 0) ? 1.0 / sqrt(2) : 1.0;
        double dctCoeff = 0;

        for (unsigned y = 0; y < BLOCK_SIZE; ++y)
        {   
            for (unsigned x = 0; x < BLOCK_SIZE; ++x)
            {   
                double uCosFactor = cos((double)(2 * x + 1) * M_PI * (double)u / (2 * (double) BLOCK_SIZE));
                double vCosFactor = cos((double)(2 * y + 1) * M_PI * (double)v / (2 * (double) BLOCK_SIZE));
                double pixel = (double)(lenaNoseGrey.at<unsigned char>(cv::Point(x,y)));
                dctCoeff += pixel * uCosFactor * vCosFactor;
            }
        }
        dctCoeff *= (2 / (double) BLOCK_SIZE) * cu * cv;
        lenaNoseDct.at<double>(cv::Point(u,v)) = dctCoeff;
    }
}   

下面是我的:

代码语言:javascript
运行
复制
for (int v = 0; v < BLOCK_SIZE; ++v)
{   
    for (int u = 0; u < BLOCK_SIZE; ++u)
    {   

        double cu = (u == 0) ? 1.0 / Math.Sqrt(2) : 1.0;
        double cv = (v == 0) ? 1.0 / Math.Sqrt(2) : 1.0;
        double dctCoeff = 0;
        double dctCoeffAlpha = 0;

        for (int y1 = 0; y1 < BLOCK_SIZE; ++y1)
        {   
            for (int x1 = 0; x1 < BLOCK_SIZE; ++x1)
            {   
                double uCosFactor = Math.Cos((2 * x1 + 1) * Math.PI * u / (2 * (double)BLOCK_SIZE));
                double vCosFactor = Math.Cos((2 * y1 + 1) * Math.PI * v / (2 * (double)BLOCK_SIZE));
                double pixel = (double)bitmapaWy1.GetPixel((x1 + 284), (y1 + 313)).R;
                double pixelalpha = (double)bitmapaWy1.GetPixel((x1 + 284), (y1 + 313)).A;
                dctCoeff += pixel * uCosFactor * vCosFactor;
                //dctCoeffAlpha += pixelalpha * uCosFactor * vCosFactor;
                dctCoeffAlpha = pixelalpha;

            }
        }
        dctCoeffAlpha *= (2 / (double)BLOCK_SIZE) * cu * cv;
        dctCoeff *= (2 / (double)BLOCK_SIZE) * cu * cv;
        macierz[u, v] = dctCoeff;

    }
}

我在我的矩阵中有不同的结果,但是当我用我的逆代码从上面的C++代码转换矩阵时,它工作得很好。你能找出我做错了什么吗?我能发现的一个区别是getpixel方法,但它是在C++代码执行的完全相同的灰度图像和图像片段上执行的。

当我将我的矩阵再次求逆到图像时,我可以看到图像,但它有很多太白或太黑的随机像素。

EN

回答 2

Stack Overflow用户

发布于 2018-09-19 18:12:19

问题解决了,问题是代码太多,我发布的实际代码正常工作,问题是我在它之后的代码,它将"dctcoeff“改为字节,并且它在循环中,所以dct的值没有重置为0;

代码语言:javascript
运行
复制
int BLOCK_SIZE = 16;
        double[,] macierz = new double[16, 16];

        for (int v = 0; v < BLOCK_SIZE; ++v)
        {
            for (int u = 0; u < BLOCK_SIZE; ++u)
            {

                 double cu = (u == 0) ? 1.0 / Math.Sqrt(2) : 1.0;
                double cv = (v == 0) ? 1.0 / Math.Sqrt(2) : 1.0;
                double dctCoeff = 0;


                for (int y1 = 0; y1 < BLOCK_SIZE; ++y1)
                {
                    for (int x1 = 0; x1 < BLOCK_SIZE; ++x1)
                    {
                        double uCosFactor = Math.Cos((2 * x1 + 1) * Math.PI * u / (2 * (double)BLOCK_SIZE));
                        double vCosFactor = Math.Cos((2 * y1 + 1) * Math.PI * v / (2 * (double)BLOCK_SIZE));
                        double pixel = bitmapaWy1.GetPixel((x1 + 284), (y1 + 313)).R;

                        dctCoeff += pixel * uCosFactor * vCosFactor;
                        //dctCoeffAlpha += pixelalpha * uCosFactor * vCosFactor;


                    }
                }

                dctCoeff *= (2 / (double)BLOCK_SIZE) * cu * cv;
                macierz[u, v] = dctCoeff;

            }
        }

这段代码工作起来就像一个护身符。我希望一些好的灵魂会使用它,因为我花了大约20个小时来使它工作。

票数 1
EN

Stack Overflow用户

发布于 2018-09-19 05:41:13

这显然是一个精度问题。

问题最有可能出现在下面这一行:

代码语言:javascript
运行
复制
 macierz[u, v] = dctCoeff;

我对以下问题也有疑问:

代码语言:javascript
运行
复制
            double pixel = (double)bitmapaWy1.GetPixel((x1 + 284), (y1 + 313)).R;
            double pixelalpha = (double)bitmapaWy1.GetPixel((x1 + 284), (y1 + 313)).A;
            dctCoeff += pixel * uCosFactor * vCosFactor;
            //dctCoeffAlpha += pixelalpha * uCosFactor * vCosFactor;
            dctCoeffAlpha = pixelalpha;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52393683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档