Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更改图像色调的更快方法?_C#_Image Processing_Hue - Fatal编程技术网

C# 更改图像色调的更快方法?

C# 更改图像色调的更快方法?,c#,image-processing,hue,C#,Image Processing,Hue,当我在轨迹栏中滑动时,有没有更好的方法可以平滑地改变图像的色调?我要做的是得到每像素的RGB值,计算饱和度和亮度,然后将值输入。图像的大小会影响色调更新的速度。Photoshop的图像色调功能将色调从0平滑地更改为360,这正是我想要尝试的 data = editImage.LockBits(new Rectangle(0, 0, editWidth, editHeight), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); byte

当我在轨迹栏中滑动时,有没有更好的方法可以平滑地改变图像的色调?我要做的是得到每像素的RGB值,计算饱和度和亮度,然后将值输入。图像的大小会影响色调更新的速度。Photoshop的图像色调功能将色调从0平滑地更改为360,这正是我想要尝试的

data = editImage.LockBits(new Rectangle(0, 0, editWidth, editHeight), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* dataPtr = (byte*)data.Scan0;
h = trackBar1.Value / 60.0;
D = 1 - Math.Abs((h % 2) - 1);

if (h >= 0 && h < 1)
{
    for (int i = 0; i < editHeight; i++)
    {
        offsetStride = i * data.Stride;
        for (int j = 0; j < editWidth; j++)
        {
            blue = dataPtr[(j * 3) + offsetStride];
            green = dataPtr[(j * 3) + offsetStride + 1];
            red = dataPtr[(j * 3) + offsetStride + 2];

            if (green > blue) max = green;
            else max = blue;
            if (red > max) max = red;

            if (green < blue) min = green;
            else min = blue;
            if (red < min) min = red;

            s = (max == 0) ? 0 : 1d - (1d * min / max);
            v = max / 255d;

            C = v * s;
            X = C * D;
            E = v - C;

            dataPtr[(j * 3) + offsetStride] = (byte)(min);
            dataPtr[(j * 3) + offsetStride + 1] = (byte)((X + E) * 255);
            dataPtr[(j * 3) + offsetStride + 2] = (byte)(max);
        }
    }
}
data=editImage.LockBits(新矩形(0,0,editWidth,editHeight),
ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
字节*dataPtr=(字节*)data.Scan0;
h=trackBar1.Value/60.0;
D=1-数学绝对值((h%2)-1);
如果(h>=0&&h<1)
{
对于(int i=0;i蓝色)最大值=绿色;
否则最大值=蓝色;
如果(红色>最大值)最大值=红色;
如果(绿色<蓝色)最小值=绿色;
else min=蓝色;
如果(红色<最小值)最小值=红色;
s=(最大值==0)?0:1d-(1d*最小值/最大值);
v=最大值/255d;
C=v*s;
X=C*D;
E=v-C;
dataPtr[(j*3)+偏移步长]=(字节)(最小值);
数据ptr[(j*3)+偏移步长+1]=(字节)((X+E)*255);
数据ptr[(j*3)+偏移步长+2]=(字节)(最大值);
}
}
}

您可以尝试使用查找表来消除“s”的计算,因为最小值和最大值的范围只能从0到255。因此您需要
s=get(min,max)
。C和E的值可能也可以保存在这个表中(但时间已经晚了,我还没有那么仔细地看)

getS表的每个元素都会像

for (int min = 0; min < 255; min++)
{
    for (int max = 0; max < 255; max++)
    {
        tableS[min, max] = (max == 0) ? 0 : 1d - (1d * min / max);
    }
}
for(int min=0;min<255;min++)
{
用于(int max=0;max<255;max++)
{
表[min,max]=(max==0)?0:1d-(1d*min/max);
}
}
Photoshop的代码可能也是用汇编语言编写的,以获得最佳性能


为了看看这是否会有很大的影响,你可以注释掉所有的色调计算代码,看看它是如何通过复制假数据来执行的。如果它像Photoshop一样快速,那么你知道这些计算是你的瓶颈。

如果你想要一个改变色调的单色图像,那么最有效的方法就是生成红色、黄色、绿色、青色、蓝色和品红图像,并根据需要在它们之间进行插值

因此,要生成10%旋转的图像,您需要添加50/60*红色+10/60*黄色并显示该图像

事实上,您并不需要生成全部6幅图像。生成红色和黄色图像就足够了。其他的可以动态生成,因为,例如,蓝色图像只是红色图像,但红色和蓝色像素交换(甚至可以从红色中导出黄色)。但也许最简单的方法是从6张图片开始,然后再添加优化

生成一个初始彩色图像的代码与上面的代码类似(乍一看),但从HSV到RGB的最后一步看起来有点可疑-wikipedia页面很好地解释了这一点(可能C#包含一个库函数来进行此转换)

[鉴于您的澄清,以下内容与您的工作无关]

如果要逐像素移动色调(因此红色变为黄色,绿色变为青色),则可以先将整个图像转换为HSV,然后再从HSV开始工作,从而节省一些时间


通过生成多个图像(例如,在色调中每旋转10度),然后在它们之间进行插值,可以节省更多时间(在变换色调时)。但它比单色的情况更复杂,因为一些像素(在插值过程中色调移动60度的倍数)需要特殊处理。因此,您还需要预先检测它们,然后动态计算它们。有一个折衷办法,即中间图像越多,在特殊情况下需要的像素就越少。实际上,通过延迟(按需)生成单独的图像可以更快地启动,因为人们通常只做一些小的更改。

我想更改整个图像的色调。因此,如果我有一个RGB图像,我将色调更改为60,该图像将看起来像一个灰度图像,上面有一个黄色滤镜。我刚刚意识到我有一个错误,并更新了上面的文本-你需要6个图像,而不是3个。预计算s和v d的值似乎会使它更快一些。我认为预先计算C是不可行的。