用C++和OpenCV生成Magic Eye立体图:让你的图像“浮“起来
Magic Eye图像(又称立体图或自动立体图)是一种特殊的二维图像,当观者放松眼部焦点时,隐藏的3D形状会神奇地"浮现"出来。这种图像在90年代风靡全球,其原理是利用**视差效应**模拟人眼的立体视觉。
·
什么是Magic Eye图像?
Magic Eye图像(又称立体图或自动立体图)是一种特殊的二维图像,当观者放松眼部焦点时,隐藏的3D形状会神奇地"浮现"出来。这种图像在90年代风靡全球,其原理是利用**视差效应**模拟人眼的立体视觉。
核心原理:
1. 重复图案基底:使用高对比度、重复性强的纹理作为背景
2. 深度映射:根据目标三维形状生成深度图
3. 视差计算:算法依据深度图水平偏移图案,创造双眼视觉差异
实现思路
我们的Magic Eye生成器包含三个关键组件:
1. 图案生成器:创建重复的背景图案
2. 深度图生成器:定义3D形状的深度信息
3. Magic Eye合成器:根据深度图偏移图案

#include <opencv2/opencv.hpp>
#include <vector>
#include <cmath>
#include <random>
#include <iostream>
using namespace cv;
using namespace std;
// 生成随机点图案
Mat generateRandomDotPattern(Size size, int dotSize = 2) {
Mat pattern(size, CV_8UC3, Scalar(255, 255, 255)); // 白色背景
// 创建随机数生成器
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> colorDist(0, 255);
uniform_int_distribution<> xDist(0, size.width - 1);
uniform_int_distribution<> yDist(0, size.height - 1);
// 添加随机点
for (int i = 0; i < size.width * size.height / 10; i++) {
int x = xDist(gen);
int y = yDist(gen);
Scalar color(colorDist(gen), colorDist(gen), colorDist(gen));
circle(pattern, Point(x, y), dotSize, color, -1);
}
return pattern;
}
// 创建深度图 - 球体
Mat createSphereDepthMap(Size size) {
Mat depthMap(size, CV_32F, Scalar(0.0f));
Point center(size.width / 2, size.height / 2);
float maxRadius = min(size.width, size.height) / 3.0f;
for (int y = 0; y < size.height; y++) {
for (int x = 0; x < size.width; x++) {
float dist = norm(Point(x, y) - center);
if (dist < maxRadius) {
// 球体深度:中心最深(值最小),边缘最浅(值最大)
float depth = 1.0f - pow(1.0f - (dist / maxRadius), 2);
depthMap.at<float>(y, x) = depth * 0.9f + 0.1f; // 0.1-1.0范围
}
else {
depthMap.at<float>(y, x) = 1.0f; // 背景最浅
}
}
}
return depthMap;
}
// 生成Magic Eye图像
Mat generateMagicEye(const Mat& pattern, const Mat& depthMap, float depthStrength = 100.0f) {
Mat result(depthMap.size(), CV_8UC3, Scalar(255, 255, 255));
// 图案宽度用于平铺
int patternWidth = pattern.cols;
for (int y = 0; y < depthMap.rows; y++) {
// 创建一行重复的图案
Mat patternRow(1, depthMap.cols + patternWidth, CV_8UC3);
for (int x = 0; x < patternRow.cols; x++) {
patternRow.at<Vec3b>(0, x) = pattern.at<Vec3b>(y % pattern.rows, x % patternWidth);
}
for (int x = 0; x < depthMap.cols; x++) {
// 根据深度计算偏移
float depth = depthMap.at<float>(y, x);
int shift = static_cast<int>(depthStrength * (1.0f - depth));
// 从重复图案中取样
if (x - shift >= 0) {
result.at<Vec3b>(y, x) = patternRow.at<Vec3b>(0, x - shift + patternWidth);
}
else {
// 边界处理
result.at<Vec3b>(y, x) = patternRow.at<Vec3b>(0, x + patternWidth);
}
}
}
return result;
}
int main() {
// 设置图像大小
Size imageSize(800, 600);
// 生成图案
Mat pattern = generateRandomDotPattern(Size(100, 100));
// 生成深度图
Mat depthMap = createSphereDepthMap(imageSize);
// 生成Magic Eye图像
Mat magicEye = generateMagicEye(pattern, depthMap/*, 80.0f*/);
// 保存结果
imwrite("magic_eye_pattern.png", pattern);
imwrite("magic_eye_depth.png", depthMap * 255);
imwrite("magic_eye_result.png", magicEye);
// 使用说明
cout << "Magic Eye图像已生成!" << endl;
cout << "观看技巧:" << endl;
cout << "1. 将图像置于眼前约30-40厘米处" << endl;
cout << "2. 放松眼睛,仿佛在看远处" << endl;
cout << "3. 尝试让眼睛'失焦',直到隐藏的3D形状浮现" << endl;
cout << "4. 可能需要几分钟的练习才能看到效果" << endl;
return 0;
}
Magic Eye效果示意图

观看技巧
1. 将图像置于眼前30-40厘米处
2. 放松眼睛,仿佛在看远处的物体
3. 尝试让眼睛"失焦",直到隐藏的3D形状浮现
4. 初次尝试可能需要1-2分钟适应
试试看吧,当你第一次成功看到图像中"浮"出的3D形状时,那种惊喜感绝对值得体验!
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)