「轉載」3D立體成像原理 - 普及篇

常用立体技术说明及对比(原创普及篇)

近来经常有朋友说如何看立体,立体眼镜如何看,个人觉得还是有必要把立体的技术再做一次通俗点的普及,根据我个人的经验,力争用最简单的语言把立体技术说清楚:

首先要搞懂什么是立体,立体对个体来说是一种感觉,这种感觉可以促使你分辨物体之间的差距,也就是空间感,而立体视像简单点说就是带有空间感的图片或者视 频,空间感的产生,是因为人的双眼每一只眼睛看到的影像是不一样的(专业用语:视觉差),(大家可以看看下图:红色部分右眼看不到,蓝色部分左眼看不到, 如下这个美女图红线内的还是有比较明显的区别,

221af18d5a46ff626079b3dc4d302786.jpg 0e0a20055dbefce2ee8d2881aa75e7d0.jpg


以上只是做一个比方,实际我们双眼看到的影像是在每个像素上都有不同,这也是平转立需要一定技术的原因。)不同的影像通过肌体传输到大脑,经大脑计算分析即可形成(医学问题不做解释),所以只有一只眼睛的人是永远感觉不到立体的。


因此,立体技术就是实现左右眼看到不同影像的技术。目前比较常用的有三种:

1、分色技术
通过不同颜色的过滤来实现,下面这幅实际上是由二张不同的图组成,分别做了红蓝渲染,当你带上红蓝眼镜时,红色镜片过滤掉渲染了红色的图片,蓝色镜片过滤 掉渲染了蓝色的图片,即可实现双眼看到不同影像。还有些红黄、红绿等等原理都是一样的。


2009-12-28 立体技术说明 003.jpg


2009-12-28 立体技术说明 004.jpg

2、分光技术

通过光的特性和折射来实现,常说的偏振观看、观屏镜观看都属于用分光技术。
偏振:利用光的特性,光是一种电磁波,是由与传播方向垂直的电场和磁场交替转换的振动形成的。自然光的震动方向是杂乱无章的,各个方向的都有,而偏振片都 可以使通过它的自然光只沿着偏振片的偏振方向振动,两个同步投影机分别将两幅不同偏振态的图像放映到银幕上再用不同偏振态的镜片分别过滤掉其中一幅图像就 可以实现立体原理。
观屏镜观看利用的是光的折射,这里不是大家很常用的就不介绍了。


2009-12-28 立体技术说明 005.jpg


2009-12-28 立体技术说明 006.jpg

3、分时技术
利用人的双眼感知特性来实现,人的眼睛是光接受器,对多少帧数的光都很敏感,但视觉神经存在暂留现象对于10帧以下的显示画面反映就看起来会拖,20帧以 上就会比较连续,60帧就不会有闪烁(为什么3D显示和投影设备都在120帧或以上的原因)在一种系统中,电视屏幕或投影交替显示两幅图片,利用专用的 LCD(液晶) 眼镜以很快的速度交替遮挡两只眼睛的视线,目前市场上三星、优派等品牌所示的3D的显示器、投影机所使用的就是以上技术,用的眼镜基本为NVIDIA。

2009-12-28 立体技术说明 007.jpg 2009-12-28 立体技术说明 007.jpg

以上三种为目前比较常用和实用的立体技术,下面再简单地谈谈其它:

最原始的技术:对眼法
这种方式就需要大家练连眼力了,俗称“对眼”,不需要任何设备,主要用于看左右格式的图片。汇聚你的视力,看中间那副图片就是立体的(有点难度)。

2009-12-28 立体技术说明 009.jpg

正在发展的技术:裸眼显示法
简单点就是把立体眼镜做到屏幕上去(注意:投影目前是没法实现的),采用的都是光栅技术,其中有包含二种1、狭缝光栅:与儿时玩的变幻画原理相同,把二幅 不同的画用技术手段显示在光栅的二边,分别投入左右眼即可;2柱镜技术:这个解释起来有些复杂,个人认为未来不会成为主流就偷懒不介绍了;

未来的技术:全真立体
看过(星球大战)电影的那种一按键人就显现出来的通讯方式,基本会跟那个相同,目前有日本和以色列实现了简单的图像立体,也就能显示些三角形、四方形的立体图,没有太大的实用价值,估计真要实现电影里的那种,怎么也要十年八年的吧。

最后给大家汇总一下:

常用立体技术对比表
2009-12-28 立体技术说明 010.jpg


这里再补充一点:由于产生立体的原因是由人体机能所导致的,因此立体影像一定是二幅或二幅以上画面组成的


常用立体格式对比表(二幅画面)
2009-12-28 立体技术说明 011.jpg



Reference:http://www.china3-d.com/Classroom/Tutorial/2009-12-28/759.html




求線段交點

#include <stdio.h>

typedef struct Point
{
double x;
double y;
}Point;


typedef struct Vector
{
struct Point begin;
struct Point end;
}Vector;


double VectorMul(Vector AB,Vector CD)/*求向量的叉积(以向量作参数)*/
{
return ((AB.end.x-AB.begin.x)*(CD.end.y-CD.begin.y) - (AB.end.y-AB.begin.y)*(CD.end.x-CD.begin.x));
}


double mul(Point A,Point B,Point C)/*向量叉积(以点做参数):求AB与AC的叉积*/
{
Point AB,AC;
AB.x=B.x-A.x;
AB.y=B.y-A.y;
AC.x=C.x-A.x;
AC.y=C.y-A.y;
return (AB.x*AC.y - AB.y * AC.x);
}


double Max(double a,double b)
{
return a > b ? a : b ;
}


double Min(double a,double b)
{
return a < b ? a : b ;
}


int Across(Vector AB,Vector CD)
/*判断线段是否相交(快速排斥试验和跨立试验)*/
{
if( /*X方向的排斥试验*/
( Max(AB.begin.x,AB.end.x) >= Min(CD.begin.x,CD.end.x) )
&&( Max(CD.begin.x,CD.end.x) >= Min(AB.begin.x,AB.end.x) )
/*Y方向的排斥试验*/
&&( Max(AB.begin.y,AB.end.y) >= Min(CD.begin.y,CD.end.y) )
&&( Max(CD.begin.y,CD.end.y) >= Min(AB.begin.y,AB.end.y) )
&&( mul(CD.begin,AB.begin,CD.end) * mul(CD.begin,AB.end,CD.end) <= 0 )/*A、B跨立CD的测试*/
&&( mul(AB.begin,CD.begin,AB.end) * mul(AB.begin,CD.end,AB.end) <= 0 )/*C、D跨立AB的测试*/
)
{
return 1;
}
return 0;
}


Point CrossPoint(Vector AB,Vector CD)
/*
求AB与CD的交点,前提:AB与CD相交
*/
{
Vector AD,AC;
Point result;
double k;
AD.begin = AB.begin;
AD.end = CD.end;
AC.begin = AB.begin;
AC.end = CD.begin;
k=(VectorMul(AB,AD))/(VectorMul(AB,AC) * 1.0);

k=k>0?k:(-k);/*这句话很重要*/

result.x = ( k * CD.begin.x + CD.end.x )/((1+k)*1.0) ;
result.y = ( k * CD.begin.y + CD.end.y )/((1+k)*1.0) ;
return result;
}


//以下是测试代码,仅供参考
int main()
{
Vector AB,CD;
Point result;

printf("Please input A:\t");
scanf("%lf%lf",&AB.begin.x,&AB.begin.y);

printf("Please input B:\t");
scanf("%lf%lf",&AB.end.x,&AB.end.y);


printf("Please input C:\t");
scanf("%lf%lf",&CD.begin.x,&CD.begin.y);


printf("Please input D:\t");
scanf("%lf%lf",&CD.end.x,&CD.end.y);

if( Across(AB,CD) )
{
result = CrossPoint(AB,CD);
printf("The Cross Point:\t");
printf("(%.2lf,%.2lf)\n",result.x,result.y);
}
else
{
printf("The segments have no cross point!\n ");
}
getchar();
getchar();
return 0;
}










C++ Reference - sort

sort


Syntax:

    #include <algorithm>
void sort( random_iterator start, random_iterator end );
void sort( random_iterator start, random_iterator end, StrictWeakOrdering cmp );


The
sort() algorithm sorts the elements in the range [start,end) into ascending
order. If two elements are equal, there is no guarantee what order they will be
in.




If the strict weak ordering function object
cmp is given, then it will be used
to compare two objects instead of the
< operator.

The algorithm behind sort() is the introsort algorithm. sort() runs in O(N log
(N)) time (average and worst case) which is faster than polynomial time but
slower than
linear time.

Note that sort() will only work with random access iterators. So you cannot use
sort() on the iterators of a “list” (linked list). Instead, you should use list's
own
sort method to sort it instead.

For example, the following code sorts a vector of integers into ascending
order:

  vector<int> v;
  v.push_back( 23 );
v.
push_back( -1 );
v.
push_back( 9999 );
v.
push_back( 0 );
v.
push_back( 4 );

cout << "Before sorting: ";
for( unsigned int i = 0; i < v.size(); i++ ) {
cout << v[i] << " ";
}
cout << endl;

sort( v.begin(), v.end() );

cout << "After sorting: ";
for( unsigned int i = 0; i < v.size(); i++ ) {
cout << v[i] << " ";
}
cout << endl;

When run, the above code displays this output:

  Before sorting: 23 -1 9999 0 4
After
sorting: -1 0 4 23 9999


Alternatively, the following code uses the
sort() function to sort a normal
array of integers, and displays the same output as the previous example:


   int array[] = { 23, -1, 9999, 0, 4 };
unsigned int array_size = 5;

cout << "Before sorting: ";
for( unsigned int i = 0; i < array_size; i++ ) {
cout << array[i] << " ";
}
cout << endl;

sort( array, array + array_size );

cout << "After sorting: ";
for( unsigned int i = 0; i < array_size; i++ ) {
cout << array[i] << " ";
}
cout << endl;

This next example shows how to use sort() with a user-specified comparison
function. The function
cmp is defined to do the opposite of the < operator.
When
sort() is called with cmp used as the comparison function, the result is a
list
sorted in descending, rather than ascending, order:

   bool cmp( int a, int b ) {
return a > b;
}

...

vector<int> v;
for( int i = 0; i < 10; i++ ) {
v.
push_back(i);
}

cout << "Before: ";
for( int i = 0; i < 10; i++ ) {
cout << v[i] << " ";
}
cout << endl;

sort( v.begin(), v.end(), cmp );

cout << "After: ";
for( int i = 0; i < 10; i++ ) {
cout << v[i] << " ";
}
cout << endl;

虹光大成就-密教灌頂(一)