Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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++ OpenCV和像Adobe Photoshop一样的反锐化掩蔽_C++_Opencv_Image Processing_Reverse Engineering_Photoshop - Fatal编程技术网

C++ OpenCV和像Adobe Photoshop一样的反锐化掩蔽

C++ OpenCV和像Adobe Photoshop一样的反锐化掩蔽,c++,opencv,image-processing,reverse-engineering,photoshop,C++,Opencv,Image Processing,Reverse Engineering,Photoshop,我正在尝试像在Adobe Photoshop中一样实现反锐化掩蔽。我收集了很多关于互联网的信息,但我不确定我是否遗漏了什么。代码如下: void unsharpMask( cv::Mat* img, double amount, double radius, double threshold ) { // create blurred img cv::Mat img32F, imgBlur32F, imgHighContrast32F, imgDiff32F, unsharpMas32F, c

我正在尝试像在Adobe Photoshop中一样实现反锐化掩蔽。我收集了很多关于互联网的信息,但我不确定我是否遗漏了什么。代码如下:

void unsharpMask( cv::Mat* img, double amount, double radius, double threshold ) {

// create blurred img
cv::Mat img32F, imgBlur32F, imgHighContrast32F, imgDiff32F, unsharpMas32F, colDelta32F, compRes, compRes32F, prod;
double r = 1.5;
img->convertTo( img32F, CV_32F );
cv::GaussianBlur( img32F, imgBlur32F, cv::Size(0,0), radius );
cv::subtract( img32F, imgBlur32F, unsharpMas32F );
// increase contrast( original, amount percent ) 
imgHighContrast32F = img32F * amount / 100.0f;
cv::subtract( imgHighContrast32F, img32F, imgDiff32F );
unsharpMas32F /= 255.0f;
cv::multiply( unsharpMas32F, imgDiff32F, colDelta32F );
cv::compare( cv::abs( colDelta32F ), threshold, compRes, cv::CMP_GT );
compRes.convertTo( compRes32F, CV_32F );

cv::multiply( compRes32F, colDelta32F, prod );
cv::add( img32F, prod, img32F );

img32F.convertTo( *img, CV_8U );
}
目前我正在用灰度图像进行测试。如果我在Photoshop中尝试完全相同的参数,我会得到更好的结果。我自己的代码会导致嘈杂的图像。我做错了什么

第二个问题是,如何在RGB图像上应用反锐化遮罩?我是否必须取消锐化3个通道中的每个通道的遮罩,或者在另一个颜色空间中效果更好?这些事情是如何在Photoshop中完成的


谢谢你的帮助

我也在尝试复制Photoshop的反锐化遮罩。 让我们暂时忽略阈值

我将向您展示如何使用高斯模糊复制Photoshop的反锐化遮罩

假设O是原始图像层

创建一个新的层GB,它是应用于O上的高斯模糊。 使用ApplyImage创建一个O-GB的新图层。 通过反转GB-invGB创建新图层。 使用图像应用创建一个新图层,该图层为O+invGB。 创建一个与上一层相反的新层,即invO+invGB。 创建一个新图层,它是O+O-GB-invO+invGB

当你在Photoshop中这样做的时候,你会得到一个完美的非锐化掩模的复制品

如果你重新计算invL=1-L,你会得到反锐化掩模是 USMO=3O-2B

然而,当我直接在MATLAB中这样做时,我并没有得到Photoshop的结果

希望有人会知道确切的数学

使现代化 嗯, 我想出来了。 在Photoshop中USMO=O+2*数量/100*O-GB 其中GB是高斯模糊版本的O


然而,为了复制Photoshop的结果,您必须执行上述步骤,并像在Photoshop中那样将每个步骤的结果剪裁到[0,1]中。

我也在尝试复制Photoshop的取消锐化遮罩。 让我们暂时忽略阈值

我将向您展示如何使用高斯模糊复制Photoshop的反锐化遮罩

假设O是原始图像层

创建一个新的层GB,它是应用于O上的高斯模糊。 使用ApplyImage创建一个O-GB的新图层。 通过反转GB-invGB创建新图层。 使用图像应用创建一个新图层,该图层为O+invGB。 创建一个与上一层相反的新层,即invO+invGB。 创建一个新图层,它是O+O-GB-invO+invGB

当你在Photoshop中这样做的时候,你会得到一个完美的非锐化掩模的复制品

如果你重新计算invL=1-L,你会得到反锐化掩模是 USMO=3O-2B

然而,当我直接在MATLAB中这样做时,我并没有得到Photoshop的结果

希望有人会知道确切的数学

使现代化 嗯, 我想出来了。 在Photoshop中USMO=O+2*数量/100*O-GB 其中GB是高斯模糊版本的O

然而,为了复制Photoshop的结果,您必须执行上述步骤,并像在Photoshop中那样将每个步骤的结果剪切到[0,1]中。

根据文档: C++:void GaussianBlur输入阵列src、输出阵列dst、大小ksize、, double sigmaX,double sigmaY=0,int borderType=BORDER\u默认值

第四个参数不是半径,而是西格玛-高斯核标准差。半径相当大。无论如何,Photoshop不是开源的,因此我们不能确定他们使用与OpenCV相同的方法从sigma计算半径

渠道 是的,您应该将夏普应用于任何或所有频道,这取决于您的目的。当然,您可以使用任何空间:如果您想要仅夏普亮度组件,并且不想增加颜色噪声,您可以将其转换为HSL或实验室空间,夏普仅L通道Photoshop也有所有这些选项。

根据文档: C++:void GaussianBlur输入阵列src、输出阵列dst、大小ksize、, double sigmaX,double sigmaY=0,int borderType=BORDER\u默认值

第四个参数不是半径,而是西格玛-高斯核标准差。半径相当大。无论如何,Photoshop不是开源的,因此我们不能确定他们使用与OpenCV相同的方法从sigma计算半径

渠道
是的,您应该将夏普应用于任何或所有频道,这取决于您的目的。当然,你可以使用任何空间:如果你想要夏普纯亮度组件,不想增加颜色噪声,你可以将其转换为HSL或实验室空间,夏普纯L通道Photoshop也有所有这些选项。

以下是我所做的代码。 我正在使用这段代码来实现反锐化掩码,它对我来说工作得很好。 希望对你有用

void USM(cv::Mat &O, int d, int amp, int threshold)
{
    cv::Mat GB;
    cv::Mat O_GB;
    cv::subtract(O, GB, O_GB);

    cv::Mat invGB = cv::Scalar(255) - GB;

    cv::add(O, invGB, invGB);

    invGB = cv::Scalar(255) - invGB;

    for (int i = 0; i < O.rows; i++)
    {
        for (int j = 0; j < O.cols; j++)
        {
            unsigned char o_rgb = O.at<unsigned char>(i, j);
            unsigned char d_rgb = O_GB.at<unsigned char>(i, j);
            unsigned char inv_rgb = invGB.at<unsigned char>(i, j);

            int newVal = o_rgb;
            if (d_rgb >= threshold)
            {
                newVal = o_rgb + (d_rgb - inv_rgb) * amp;
                if (newVal < 0)      newVal = 0;
                if (newVal > 255)    newVal = 255;
            }

            O.at<unsigned char>(i, j) = unsigned char(newVal);
        }
    }

}

这是我所做的代码。 我正在使用这段代码来实现反锐化掩码,它对我来说工作得很好。 希望对你有用

void USM(cv::Mat &O, int d, int amp, int threshold)
{
    cv::Mat GB;
    cv::Mat O_GB;
    cv::subtract(O, GB, O_GB);

    cv::Mat invGB = cv::Scalar(255) - GB;

    cv::add(O, invGB, invGB);

    invGB = cv::Scalar(255) - invGB;

    for (int i = 0; i < O.rows; i++)
    {
        for (int j = 0; j < O.cols; j++)
        {
            unsigned char o_rgb = O.at<unsigned char>(i, j);
            unsigned char d_rgb = O_GB.at<unsigned char>(i, j);
            unsigned char inv_rgb = invGB.at<unsigned char>(i, j);

            int newVal = o_rgb;
            if (d_rgb >= threshold)
            {
                newVal = o_rgb + (d_rgb - inv_rgb) * amp;
                if (newVal < 0)      newVal = 0;
                if (newVal > 255)    newVal = 255;
            }

            O.at<unsigned char>(i, j) = unsigned char(newVal);
        }
    }

}

作为对@Royi的响应,2x乘数是由于在该公式中假设无箝位而产生的:

USM(Original) = Original + Amount / 100 * ((Original - GB) - (1 - (Original + (1 - GB))))
忽略夹紧,这将导致:

USM(Original) = Original + 2 * Amount / 100 * (Original - GB) 
USM(Original) = Original + Amount / 100 * (Original - GB)
但是,正如您所指出的,Original-GB和Origin al+invGB被钳制到[0,1]:

USM(Original) = Original + Amount / 100 *
   (Max(0, Min(1, Original - GB)) - (1 - (Max(0, Min(1, Original + (1 - GB))))))
这正确地归结为:

USM(Original) = Original + 2 * Amount / 100 * (Original - GB) 
USM(Original) = Original + Amount / 100 * (Original - GB)
以下是一个示例,说明了原因:


作为对@Royi的响应,2x乘数是由于在该公式中假设无箝位而产生的:

USM(Original) = Original + Amount / 100 * ((Original - GB) - (1 - (Original + (1 - GB))))
忽略夹紧,这将导致:

USM(Original) = Original + 2 * Amount / 100 * (Original - GB) 
USM(Original) = Original + Amount / 100 * (Original - GB)
但是,正如您也指出的,Original-GB和Original+invGB被钳制到[0,1]:

USM(Original) = Original + Amount / 100 *
   (Max(0, Min(1, Original - GB)) - (1 - (Max(0, Min(1, Original + (1 - GB))))))
这正确地归结为:

USM(Original) = Original + 2 * Amount / 100 * (Original - GB) 
USM(Original) = Original + Amount / 100 * (Original - GB)
以下是一个示例,说明了原因:


你是如何在这个公式中找到神奇的2*乘数的?我在pixastic和其他源代码中也看到过同样的数学,但是没有2x乘法,尽管通过理解Photoshop的功能,它们并不假装等于Photoshop。你能看看这个演示吗?我已经实现了你的公式。将其应用于亮度0.299*R+0.587*G+0.114*B。然后发现亮度差用于缩放RBG通道。这么大的不锐化量会导致颜色漂移吗?@Vitaly,我不确定我是否理解你的意思。无论如何,Photoshop将其应用于所有RGB通道。如果只需要亮度,则需要通过转换来实现。@Vitaly,正如我所说,默认情况下,它在所有通道上独立工作。如果只想将其应用于亮度,可以使用混合模式进行,也可以转到实验室,选择L通道,应用并转换回。同样,它对输入图像的所有通道都起作用。你是如何在这个公式中找到神奇的2*乘法器的?我在pixastic和其他源代码中也看到过同样的数学,但是没有2x乘法,尽管通过理解Photoshop的功能,它们并不假装等于Photoshop。你能看看这个演示吗?我已经实现了你的公式。将其应用于亮度0.299*R+0.587*G+0.114*B。然后发现亮度差用于缩放RBG通道。这么大的不锐化量会导致颜色漂移吗?@Vitaly,我不确定我是否理解你的意思。无论如何,Photoshop将其应用于所有RGB通道。如果只需要亮度,则需要通过转换来实现。@Vitaly,正如我所说,默认情况下,它在所有通道上独立工作。如果只想将其应用于亮度,可以使用混合模式进行,也可以转到实验室,选择L通道,应用并转换回。同样,它在输入图像的所有通道上运行。我想你的意思是说转换为HSV,而不是HSL,如果你只想提高亮度的话。V是亮度。L是轻盈。锐化V避免了颜色偏移。我想如果你只想锐化亮度,你的意思是说转换为HSV,而不是HSL。V是亮度。L是轻盈。锐化V避免了颜色偏移。