goo*_*dev 1 c++ photoshop opencv image-processing
我想像 Adobe Photoshop 一样应用不清晰的蒙版,我知道这个答案,但它不如 Photoshop 清晰。
Photoshop 在 Smart Sharpen 对话框中有 3 个参数:Amount、Radius、Reduce Noise;我想实现所有这些。

根据 SO 中的各种来源,这是我编写的代码。但是在某些阶段(“blurred”、“unsharpMask”、“highContrast”)结果很好,但在最后阶段(“retval”)结果不好。
我哪里错了,我应该改进什么?
是否可以在性能方面改进以下算法?
#include "opencv2/opencv.hpp"
#include "fstream"
#include "iostream"
#include <chrono>
using namespace std;
using namespace cv;
// from https://docs.opencv.org/3.4/d3/dc1/tutorial_basic_linear_transform.html
void increaseContrast(Mat img, Mat* dst, int amountPercent)
{
*dst = img.clone();
double alpha = amountPercent / 100.0;
*dst *= alpha;
}
// from /sf/answers/41737041/
float luminanceAsPercent(Vec3b color)
{
return (0.2126 * color[2]) + (0.7152 * color[1]) + (0.0722 * color[0]);
}
// from /sf/answers/205685581/
Mat usm(Mat original, int radius, int amountPercent, int threshold)
{
// copy original for our return value
Mat retval = original.clone();
// create the blurred copy
Mat blurred;
cv::GaussianBlur(original, blurred, cv::Size(0, 0), radius);
cv::imshow("blurred", blurred);
waitKey();
// subtract blurred from original, pixel-by-pixel to make unsharp mask
Mat unsharpMask;
cv::subtract(original, blurred, unsharpMask);
cv::imshow("unsharpMask", unsharpMask);
waitKey();
Mat highContrast;
increaseContrast(original, &highContrast, amountPercent);
cv::imshow("highContrast", highContrast);
waitKey();
// assuming row-major ordering
for (int row = 0; row < original.rows; row++)
{
for (int col = 0; col < original.cols; col++)
{
Vec3b origColor = original.at<Vec3b>(row, col);
Vec3b contrastColor = highContrast.at<Vec3b>(row, col);
Vec3b difference = contrastColor - origColor;
float percent = luminanceAsPercent(unsharpMask.at<Vec3b>(row, col));
Vec3b delta = difference * percent;
if (*(uchar*)&delta > threshold) {
retval.at<Vec3b>(row, col) += delta;
//retval.at<Vec3b>(row, col) = contrastColor;
}
}
}
return retval;
}
int main(int argc, char* argv[])
{
if (argc < 2) exit(1);
Mat mat = imread(argv[1]);
mat = usm(mat, 4, 110, 66);
imshow("usm", mat);
waitKey();
//imwrite("USM.png", mat);
}
Run Code Online (Sandbox Code Playgroud)
小智 6
首先,从 Photoshop 在花瓣边缘留下的人工制品来看,我会说它通过使用原始图像和蒙版之间的加权和来应用蒙版,如您首先尝试的答案。
我修改了你的代码来实现这个方案,我试图调整参数以接近 Photoshop 结果,但我不能不产生很多噪音。我不会试图猜测 Photoshop 到底在做什么(我绝对想知道),但是我发现通过在蒙版上应用一些过滤器来减少噪音,它是相当可重现的。算法方案是:
blurred = blur(image, Radius)
mask = image - blurred
mask = some_filter(mask)
sharpened = (mask < Threshold) ? image : image - Amount * mask
Run Code Online (Sandbox Code Playgroud)
我实现了这个并尝试在蒙版上使用基本过滤器(中值模糊、平均过滤器等),这是我可以获得的结果:

这比 Photoshop 图像有点嘈杂,但在我看来,已经足够接近你想要的了。
另一方面,这当然取决于您对滤镜的使用,但我认为您在 Photoshop 中使用的设置太强了(花瓣边界附近有很大的过冲)。这足以在肉眼下获得漂亮的图像,并且过冲有限:

最后,这是我用来生成上面两个图像的代码:
blurred = blur(image, Radius)
mask = image - blurred
mask = some_filter(mask)
sharpened = (mask < Threshold) ? image : image - Amount * mask
Run Code Online (Sandbox Code Playgroud)