什么是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形状时,那种惊喜感绝对值得体验!

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐