如何使用OpenCV恢复照片?

如何使用OpenCV恢复照片?,opencv,image-processing,colors,Opencv,Image Processing,Colors,我有一张灰度照片,我正试图通过编程给它上色,让它看起来“真实”,用户输入“绘制”颜色(如红色)。感觉应该很简单,但我一直在尝试一些看起来不合适的方法,所以我想我应该问问社区,以防我错过了一些明显的东西。我试过以下方法 转换为HSV,并将用户选择的颜色的“色调”和饱和度与图像的“值”相结合 构建颜色变换矩阵以乘以BGR值(即R=0.8R+1.1G+1.0B)。这对“着色”效果很好,并添加了一个很好的粉彩效果,但并不能真正保持我想要的颜色的深度或粗犷 (到目前为止最喜欢的-参见答案)将颜色通道的R

我有一张灰度照片,我正试图通过编程给它上色,让它看起来“真实”,用户输入“绘制”颜色(如红色)。感觉应该很简单,但我一直在尝试一些看起来不合适的方法,所以我想我应该问问社区,以防我错过了一些明显的东西。我试过以下方法

  • 转换为HSV,并将用户选择的颜色的“色调”和饱和度与图像的“值”相结合
  • 构建颜色变换矩阵以乘以BGR值(即R=0.8R+1.1G+1.0B)。这对“着色”效果很好,并添加了一个很好的粉彩效果,但并不能真正保持我想要的颜色的深度或粗犷
  • (到目前为止最喜欢的-参见答案)将颜色通道的RGB乘以图像的RGB

为了补充用户Alexander Reynolds的评论,您提出的问题是计算机图形学领域中一个已知的开放研究问题,因为在不使用某种统计先验的情况下,该问题受到约束。CG社区的最新技术可在此找到,并在SIGGRAPH 2016上展示

另见:

我对photoshop进行了另一番思考,并在BGR空间上实现了多重混合模式,以获得一个ok的结果。 用java实现

Mat multiplyBlend(Mat值,Mat颜色){//值1通道,颜色3
//模拟BGR多重混合模式
ArrayList SplitColors=新的ArrayList();
核心。拆分(颜色,拆分颜色);
Core.multiply(值,splitcolors.get(0),splitcolors.get(0),1/255.0f);
Core.multiply(值,splitcolors.get(1),splitcolors.get(1),1/255.0f);
Core.multiply(值,splitcolors.get(2),splitcolors.get(2),1/255.0f);
Mat ret=新Mat();
核心。合并(拆分颜色,ret);
返回ret;
}

灰度图像没有颜色信息,因此无法提取。如果没有机器学习能够找出图像中应该存在的颜色,它将永远不会看起来“真实”。有关应用于此问题的CNN示例,请参见。否则,有许多不同的方法以非真实的方式对图像进行着色,但问题需要重新表述,以确定您想要实现的目标,并准确显示您当前的方法如何未能达到该目标。用户将选择哪种颜色,我的问题是使灰度图像看起来像那种颜色,并尽可能保持功能的“丰富性”(例如,在上面画一个透明的矩形颜色会将其洗掉,在我的HSV方法中,饱和层的问题)。我希望通过用户的输入以一种看似合理的方式进行着色。再次,请包括您想要实现的目标以及您的方法如何未能达到目标。我今天看到并想到了您的帖子。感谢您的帮助-再次尝试HSV混合(使用颜色中的HS和灰度图像中的V),它最终看起来太“卡通化”了,而且不能很好地处理灰色。我可以通过在颜色值和灰色图像之间求平均值来解决第二个问题,但仍然不对。倍增效果看起来更暗,但在我的应用程序中更真实。我可能需要尝试几种不同的方法(例如检测灰色并以不同的方式处理它们,并可能纠正由倍增效应产生的黑暗:按平均亮度缩放)。我意识到我的问题遗漏了信息:用户/我正在选择颜色(例如深红色),我的问题是让它看起来像图像中的灰色物体是红色的。程序不需要选择要使用的颜色。我怀疑这不需要机器学习,但不确定采取什么方法。似乎用户应该选择色调和饱和度(HSV颜色空间中的H和S),然后V(值)分量可以来自灰度图像。因为灰度只是给你一个关于场景整体亮度的线索。
Mat multiplyBlend(Mat values, Mat colours) {//values 1 channel, colours 3
    //simulates BGR Multiply blend mode 
    ArrayList<Mat> splitColours = new ArrayList<Mat>();
    Core.split(colours, splitColours);
    Core.multiply(values, splitColours.get(0), splitColours.get(0), 1/255.0f);
    Core.multiply(values, splitColours.get(1), splitColours.get(1), 1/255.0f);
    Core.multiply(values, splitColours.get(2), splitColours.get(2), 1/255.0f);
    Mat ret = new Mat();
    Core.merge(splitColours, ret);
    return ret;
}