OpenCV 4.11.0
开源计算机视觉库
加载中…
搜索中…
无匹配项
信息流阿尔法抠图

此项目是 Google Summer of Code 2019 的一部分。

学生:Muskaan Kularia

导师:Sunita Nayak

阿尔法抠图问题是从背景图像中提取具有柔和边界的目标前景。提取的前景可用于进一步操作,例如更改图像中的背景。

给定输入图像及其对应的三值图,我们尝试从背景中提取前景。以下是一个示例

输入图像:

输入图像最好是 RGB 图像。

输入三值图:

三值图是灰度图像,包含有关前景(白色像素)、背景(黑色像素)和未知(灰色)像素的信息。

输出阿尔法蒙版:

计算的阿尔法蒙版保存为灰度图像,其中像素值指示提取的前景对象的透明度。这些透明度值可用于将前景对象混合到不同的背景中,如下所示:

以下是一些其他的结果。

第一列是输入 RGB 图像,第二列是输入三值图,第三列是提取的阿尔法蒙版,最后两列显示混合在新背景上的前景对象。

此项目是 [7] 的实现。它还需要实现其他论文 [2,3,4] 的部分内容。

构建

此模块使用 Eigen 包。

使用以下两个 cmake 命令在 build 文件夹内运行,来构建 alphamat 模块的示例代码

cmake -DOPENCV_EXTRA_MODULES_PATH=<opencv_contrib 模块路径> -DBUILD_EXAMPLES=ON ..
cmake --build . --config Release --target example_alphamat_information_flow_matting

如有需要,请参考 OpenCV 构建教程了解更多详细信息。

测试

构建的目标可以按如下方式测试

<opencv 构建目录路径>/bin/example_alphamat_information_flow_matting -img=<输入图像文件路径> -tri=<对应三值图路径> -out=<保存输出蒙版文件路径>

示例源代码

1// 此文件是 OpenCV 项目的一部分。
2// 它受此发行版顶层目录中 LICENSE 文件中找到的许可条款以及 https://opencv.ac.cn/license.html 中的许可条款的约束。
3
4
5// 包含相关的头文件
6#include <iostream>
7#include "opencv2/highgui.hpp"
8#include <opencv2/core.hpp>
9#include <opencv2/imgproc.hpp>
10#include <opencv2/alphamat.hpp>
11
12// 设置命名空间
13using namespace std;
14using namespace cv;
15using namespace cv::alphamat;
16
17// 设置使用参数名称
18const char* keys =
19 "{img || 输入图像名称}"
20 "{tri || 输入三值图图像名称}"
21 "{out || 输出图像名称}"
22 "{help h || 打印帮助信息}"
23;
24
25int main(int argc, char* argv[])
26{
27 CommandLineParser parser(argc, argv, keys);
28 parser.about("此示例演示信息流阿尔法抠图");
29
30 if (parser.has("help"))
31 {
32 parser.printMessage();
33 return 0;
34 }
35
36 // 读取输入图像、输入三值图和输出图像的位置的路径。
37 string img_path = parser.get<std::string>("img");
38 string trimap_path = parser.get<std::string>("tri");
39 string result_path = parser.get<std::string>("out");
40
41 // 确保用户输入输入图像和三值图的路径
42 if (!parser.check()
43 || img_path.empty() || trimap_path.empty())
44 {
45 parser.printMessage();
46 parser.printErrors();
47 return 1;
48 }
49
50 Mat image, tmap;
51
52 // 读取输入图像
53 image = imread(img_path, IMREAD_COLOR);
54 if (image.empty())
55 {
56 printf("无法读取图像文件:'%s'\n", img_path.c_str());
57 return 1;
58 }
59
60 // 读取三值图
61 tmap = imread(trimap_path, IMREAD_GRAYSCALE);
62 if (tmap.empty())
63 {
64 printf("无法读取trimap文件: '%s'\n", trimap_path.c_str());
65 return 1;
66 }
67
68 Mat result;
69 // 执行信息流阿尔法抠图
70 infoFlow(image, tmap, result);
71
72 if (result_path.empty())
73 {
74 // 如果未提供结果文件路径,则显示阿尔法蒙版。
75 namedWindow("结果阿尔法蒙版", WINDOW_NORMAL);
76 imshow("结果阿尔法蒙版", result);
77 waitKey(0);
78 }
79 else
80 {
81 // 保存阿尔法蒙版
82 imwrite(result_path, result);
83 printf("结果已保存: '%s'\n", result_path.c_str());
84 }
85
86 return 0;
87}
用于命令行解析。
定义 utility.hpp:890
n维密集数组类
定义 mat.hpp:829
bool empty() const
如果数组没有元素,则返回true。
void infoFlow(InputArray image, InputArray tmap, OutputArray result)
计算图像中对象的阿尔法蒙版。
void imshow(const String &winname, InputArray mat)
在指定的窗口中显示图像。
int waitKey(int delay=0)
等待按键按下。
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
创建窗口。
CV_EXPORTS_W bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
将图像保存到指定文件。
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
从文件中加载图像。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
定义 alphamat.hpp:25
定义 core.hpp:107
STL 命名空间。

参考文献

[1] Yagiz Aksoy, Tunc Ozan Aydin, Marc Pollefeys, 设计有效的像素间信息流用于自然图像抠图, CVPR, 2017.

[2] Roweis, Sam T. 和 Lawrence K. Saul. 通过局部线性嵌入进行非线性降维, Science 290.5500 (2000): 2323-2326.

[3] Anat Levin, Dani Lischinski, Yair Weiss, 自然图像抠图的闭合解, IEEE TPAMI, 2008.

[4] Qifeng Chen, Dingzeyu Li, Chi-Keung Tang, KNN抠图, IEEE TPAMI, 2013.

[5] Yagiz Aksoy, 基于亲和性的抠图工具箱.