亚洲成年人黄色一级片,日本香港三级亚洲三级,黄色成人小视频,国产青草视频,国产一区二区久久精品,91在线免费公开视频,成年轻人网站色直接看

三維成像系統(tǒng)的制作方法

文檔序號:7567824閱讀:552來源:國知局
專利名稱:三維成像系統(tǒng)的制作方法
技術(shù)領(lǐng)域
本發(fā)明涉及三維圖像顯示技術(shù),并特別涉及一種其中無需采用特殊頭戴裝置或眼鏡的技術(shù)。
全三維圖像地顯示已成為二十世紀(jì)繁榮時期的一個重大科技目標(biāo)。早在1908年,Gabriel Lippman發(fā)明了一種采用通過微小定位透鏡組成的“蠅眼”微透鏡板曝光照像底片來產(chǎn)生一景物的真實三維圖像的方法。此技術(shù)即有名的“整體攝影術(shù)”(integral photography),其改進(jìn)圖像的顯示通過同種定位透鏡的微透鏡板得以實施。然而,Lippman歷經(jīng)多年的改進(jìn)及其發(fā)展(例如,美國專利No.3,878,329)并不能提供適于如下要求圖像的技術(shù),即圖像要易于產(chǎn)生,可用于運動顯示,或能夠再現(xiàn)電子生成圖像這種本世紀(jì)后半葉的主要圖像形式。
隨著時間的推移,三維圖像的多像組分方法(multiple-image-component approach)已擴展成多種技術(shù)改進(jìn),它包括條狀微透鏡板或網(wǎng)格板的光學(xué)元件的種種實施方案,用以從單個特殊處理的圖像產(chǎn)生立體圖像(例如,美國專利No.4,957,311或美國專利No.4,729,017,引用最近相關(guān)實施例)。絕大多數(shù)此類實施例都受到通常的一系列缺陷的困擾,包括對觀察者相對于觀察屏的身體位置的嚴(yán)格限制,由于在兩幅分離圖像之間分割生成圖像亮度而導(dǎo)致的象質(zhì)降低,并且在多數(shù)情況下,視差僅在一個方向可觀察到。
產(chǎn)生真實三維圖像的其他現(xiàn)有技術(shù)包括對物理空間的掃描,或者利用在一旋轉(zhuǎn)的螺旋面屏幕或散射蒸氣云上以激光束進(jìn)行機械掃描,相繼激活陰極射線管中的大量內(nèi)部熒光屏的辦法;或者通過使一可彎曲的彎曲反射鏡發(fā)生物理偏移以產(chǎn)生傳統(tǒng)成像裝置的可變焦型式。所有這些技術(shù)已被證明很麻煩,既難于制造也不便觀看,總的說來不適于在消費市場推廣應(yīng)用。
在此期間,出現(xiàn)了大量關(guān)于觀察者配戴裝置的技術(shù),包括采用雙色或正交偏振濾光片以分離同時顯示的兩幅圖像的眼鏡,及虛擬現(xiàn)實顯示頭戴裝置,其都與產(chǎn)生立體觀測效果有關(guān),這就是說,通過使分離的左右眼圖像同化而察覺深度。其中有一些已能產(chǎn)生非常高質(zhì)量的立體圖像,但一般其代價為觀察者的舒適與方便,眼睛緊張,圖像亮度,及讓那些不愿或不適觀看此立體圖像的觀眾接受。所有這些代價即為最近出現(xiàn)的眼科學(xué)與神經(jīng)學(xué)研究的主體,該研究認(rèn)為持續(xù)使用立體成像系統(tǒng),使用者配戴物等等導(dǎo)致了有害且潛在的持久效果。
本發(fā)明試圖提供一種改進(jìn)的三維成像裝置,它結(jié)構(gòu)緊湊簡單,且無須觀察者使用任何眼鏡,虛擬真實頭戴裝置或任何其他用戶設(shè)備。
為提供這種改進(jìn)的三維成像裝置,本發(fā)明通過改變圖像的各個像素到觀察點的距離來產(chǎn)生三維圖像。本發(fā)明采用了一系列特別小的特殊設(shè)計的光學(xué)單元陣列,它們設(shè)置成可使其焦距沿此光學(xué)單元的表面而變化。通過精細(xì)移動入射到屬于一幅圖像內(nèi)不同像素的光學(xué)單元的光束之入射點,可向觀察者展示一幅完整圖像,其中一些單元距觀察者較近而另一些較遠(yuǎn),就象真實世界中的景象一樣。此顯示的圖像沒有畸變,觀察者眼睛對圖像的較近部分聚焦較近,對圖像的較遠(yuǎn)部分聚焦較遠(yuǎn)。
本發(fā)明明顯不依賴于由觀察者左右眼分離圖像而產(chǎn)生的深度察覺,因而克服了部分立體圖像中常有的更持久和更嚴(yán)重的缺陷。
在一個優(yōu)選實施例中光學(xué)單元制成為一個或多個透鏡,但也可代之以制成反射鏡或甚至為折射與反射面的結(jié)合。
在其最簡形式中,像素及上覆光學(xué)單元為矩形,每個光學(xué)單元的焦距沿其長度方向逐漸改變。在此情況下,光束的入射點沿此長度線性位移。然而,其他形狀的光學(xué)單元及位移形式仍在本發(fā)明范圍內(nèi)。例如,光學(xué)單元可為圓形,具有可相對于中央光軸徑向改變的焦距。在此情況下,光束以徑向分布的環(huán)狀帶入射。
同樣,雖然此處像素級光學(xué)單元的光學(xué)特性的改變是以由物理單元表面的外形改變所引起來加以說明的,但我們在實驗室中已試驗成功,通過采用其折射率沿光學(xué)單元逐漸改變的梯度系數(shù)光學(xué)材料,來產(chǎn)生光學(xué)特性的此種改變。
焦距與位移之間的關(guān)系可以是線性或非線性的。
可采用多種裝置來提供入射至像素級光學(xué)器件陣列的像素級光束。在本發(fā)明的一個實施例中,這種光輸入裝置為設(shè)在光學(xué)器件陣列后的陰極射線管,以使一束光可在每一行像素級光學(xué)器件后進(jìn)行水平掃描,并且在其通過每個光學(xué)器件后產(chǎn)生一相對掃描線的細(xì)微區(qū)別的垂直位移。在不同實施例中,此光輸入裝置可為一平板顯示裝置,諸如液晶,場致發(fā)光技術(shù)的或等離子體顯示裝置。場致發(fā)光裝置包括LED(發(fā)光二極管)陣列。在所有這些實施例中,運動圖像是通過依次掃描整個圖像來產(chǎn)生的,并以與傳統(tǒng)二維運動圖像所采用的相同方式來進(jìn)行。在此方式中,運動圖像可以僅受對每一像素掃描光束精細(xì)垂直控制能力限制的幀頻產(chǎn)生。本技術(shù)并無限制范圍,此處描述的本發(fā)明實施例已在我們實驗室中成功地以達(dá)到每秒111幀的幀頻實施。
在另一優(yōu)選實施例中,像素級整幅圖像的照度來自特殊制備的運動畫面或攝影透明膠片,其中每幀膠片以傳統(tǒng)方式后部照明,但通過上述同樣類型的像素級光學(xué)元件來觀看。在此實施例中,每個透明片格中每一透射光像素沿著光學(xué)元件的入射表面特別設(shè)置,以使其入射垂直點能在離觀察者觀看此特定像素所需特定距離處產(chǎn)生一個光點,如上面電子照明實施例一樣。這種傳統(tǒng)公知系統(tǒng)含有通過由凹面鏡或類似圖像投射光學(xué)器件反射將三維圖像投射到自由空間。此技術(shù)比傳統(tǒng)平面二維圖像的投影具有顯著優(yōu)越性,因為位于自由空間的被投射三維圖像實際上具有真實的可視的深度。迄今為止,我們已成功采用具有球面、拋物面和雙曲面數(shù)學(xué)曲面的凹面反射鏡,但顯然其他凹面形狀也是可能的。
本發(fā)明的這些及其他目的和優(yōu)點通過下述說明結(jié)合附圖考察將變得很清楚。在所有這些圖示中,相同部分以相同標(biāo)記數(shù)碼指示


圖1(a)為像素級光學(xué)元件的一個實施例由后部斜視的示意圖1(b)為具有三個光學(xué)單元的同類像素級光學(xué)組件的另一實施例的示意圖。
圖2說明了通過改變準(zhǔn)直光束在像素級光學(xué)元件后部(輸入端)的入射點,從而改變光點出射處距觀察者的空間距離之方式。
圖3(a)說明在一優(yōu)選實施例中,對像素級光學(xué)元件的這種變化,入射照明是如何由陰極射線管提供的。
圖3(B)顯示了這種改變?nèi)肷湔彰鞯牧硪灰晥D,以及像素級光學(xué)器件與陰極射線管的熒光層上像素的對準(zhǔn);
圖3(c)說明了準(zhǔn)直入射光束的尺寸和縱橫比率與像素級光學(xué)元件的尺寸和縱橫比率之間的關(guān)系。
圖4(a)說明像素級光學(xué)器件是如何設(shè)置在照明光源前的,如計算機監(jiān)視器,電視的陰極射線管或其他大致平面屏幕成像裝置。
圖4(b)顯示了為此目的可采用的圖像柱像素的第二優(yōu)選模式。
圖5說明了在電視或計算機監(jiān)視器圖像中將深度信號加入水平掃描柵線中的方式。
圖6說明如何利用動畫膠片或一些其他形式的照明透明片作為照明源,改變?nèi)肷涞较袼丶壒鈱W(xué)元件的光的特定點。
圖7說明在三維運動圖片顯示中,如何采用像素級光學(xué)元件陣列來觀看一條連續(xù)動畫電影以顯示電影的依次片格。
圖8說明通過采用一個主成像鏡頭和一個輔鏡頭捕捉圖像,可得出記錄景象的深度成份的方法。
圖9(a)說明了在傳統(tǒng)二維圖像中倒推深度信號的過程,進(jìn)而使此圖像能在一適當(dāng)顯示裝置上以三維顯示。
圖9(b)顯示用于根據(jù)圖9(a)所示過程將深度加入視頻圖像的圖像處理裝置的聯(lián)接及工作原理。
圖10顯示了在印刷圖像的三維顯示改進(jìn)過程中導(dǎo)出的像素深度顯示技術(shù)的應(yīng)用。
圖11說明了傳統(tǒng)NTSC視頻信號的能量分布,顯示了亮度及色度載波。
圖12說明了相同的NTSC視頻信號能量分布,但將深度信號編碼到頻譜中。
圖13(a)說明了傳統(tǒng)電視接收機中電路系統(tǒng)的功能設(shè)計,它按常規(guī)控制掃描電子束在陰極射線管中的垂直偏轉(zhuǎn)。
圖13(b)顯示了同樣的電路系統(tǒng),它加入了從三維編碼視頻信號解碼深度成份以及將掃描電子束的垂直偏轉(zhuǎn)行為適當(dāng)轉(zhuǎn)換以產(chǎn)生三維效果所需的電路。
圖14顯示了基于電視的實現(xiàn)圖13(b)所示的深度提取與顯示功能的電子線路的一個優(yōu)選實施例。
圖15顯示了另一種像素級光學(xué)結(jié)構(gòu),其中輸入光的位置輻射狀變化,而非直線式變化。
圖16與圖2近似,但顯示了改變單個像素出射光相對觀察者的視覺距離的另一種方法。
圖17說明如何在一實際實施例中實現(xiàn)圖16所示的安排。
圖1(a)以大比例放大形式顯示了光學(xué)單元2的一個可能實施例,它用以改變到觀察者的距離,在該距離處入射到此元件的光束可能會聚成點。作為參考,此光學(xué)單元的尺寸可明顯變化,但應(yīng)能與顯示像素的尺寸相配,這樣,對于電視顯示器,其尺寸典型為1mm寬3mm高的量級。小至0.5mm×1.5mm的光學(xué)元件可用于設(shè)計為近距離觀看的計算機顯示器的顯示,而大至5mm寬15mm高的尺寸可用于設(shè)計為相當(dāng)遠(yuǎn)距離觀看的大型商用顯示裝置。
制作這些像素級光學(xué)器件的材料,迄今為止,為熔融石英玻璃(折射率1.498043),或下列兩種塑料之一,即聚甲基丙烯酸甲酯(折射率1.498)或甲基丙烯酸甲酯(折射率1.558)。然而,此處并不表明,這些是制造此種像素級光學(xué)元件僅有的,或甚至是優(yōu)選光學(xué)材料。
在圖1(a)中,像素級光學(xué)單元由后部斜視,將可看到,雖然此光學(xué)元件的前表面1從頂至底都是凸的,但其后表面形狀從頂部的凸形逐漸變至底部的凹形。此光學(xué)特征變化的線性和非線性過程都已成功采用。準(zhǔn)直光束沿光軸3的方向投射至此光學(xué)元件,將會看到,準(zhǔn)直光束通過的會聚光學(xué)折射表面將隨著入射點從元件頂部到底部的移動而改變。
雖然圖1(a)所示實施例具有一個固定表面和一個可變表面,但也可設(shè)計為兩個表面都可變,或者具有多于兩個光學(xué)折射表面。例如圖1(b),顯示了第二實施例,其中像素級光學(xué)元件是具有三個光學(xué)單元的復(fù)合光學(xué)元件。實驗室中的測試表明,復(fù)合像素級光學(xué)組件可提供相對單個單元光學(xué)組件改善的像質(zhì)和改進(jìn)的視角,而事實上本技術(shù)迄今最成功的實施例采用了三單元光學(xué)器件。然而,由于單個單元光學(xué)組件如此處所述在本發(fā)明中確實有效,所以為清楚說明起見,本說明書中所示的像素級光學(xué)組件將以單個單元光學(xué)組件加以描述。
為清楚顯示,圖2以壓縮形式顯示了在像素級光學(xué)單元2之前一定距離的觀察者眼睛4。準(zhǔn)直光束以不同點入射至光學(xué)元件2的背面,其中三束以光束5,6和7表示。由于器件2的焦距隨光束入射點不同而變化,圖2說明了光束的生成點如何在空間以不同出現(xiàn)點5a,6a或7a處呈現(xiàn)給觀察者,對應(yīng)于入射光束的前述特殊且標(biāo)號的位置。雖然點5a,6a和7a實際上互相有一垂直位移,但這種垂直位移觀察者是察覺不到的,只能看見深度上的明顯位移。
圖3(a)顯示,在本發(fā)明一個優(yōu)選實施例中,每一單個像素級光學(xué)元件如何被設(shè)置在用作照明光源的陰極射線管表面上。此圖中,光學(xué)單元2設(shè)置在陰極射線管的玻璃前面8上,其后即為通常的熒光層9,它在被投射的準(zhǔn)直電子束撞擊時發(fā)光,電子束此圖中以束5b,6b和7b表示不同位置。對于這些圖示的三電子束位置,以及對于此像素級光學(xué)元件的空間范圍內(nèi)的任意其他電子束位置,一點處的光將會入射到像素級光學(xué)元件背面的唯一點上。電子束的垂直位置完全可通過采用傳統(tǒng)陰極射線管所見的傳統(tǒng)電磁射束定位線圈加以改變,對于特定信號,雖然實驗中進(jìn)行的實驗表明,高幀頻,即大致超過100幀每秒顯示的圖像,需要的射束定位線圈應(yīng)構(gòu)造成對與高幀頻相聯(lián)系的較高偏轉(zhuǎn)頻率應(yīng)更加靈敏。然而,陰極射線管上熒光物質(zhì)的分布模式必須既在長度也在空間設(shè)置上與像素級光學(xué)元件的設(shè)置相配,這就是說,光學(xué)元件必須能到其下熒光物質(zhì)在其被設(shè)計出的整個線性輸入表面的照明。圖3(b)通過像素級光學(xué)元件2的斜后視圖表示了這種設(shè)置。此圖中,相鄰熒光像素35,畫出了9個,用于傳統(tǒng)彩色陰極射線管中的三種不同顏色,且具有大體矩形的形狀。注意每一熒光像素的尺寸和縱橫化(即長寬比)應(yīng)與之面對的像素級光學(xué)元件的輸入端的尺寸和縱橫比大體相配。通過觀察陰影所代表熒光像素,將會看到,掃描此熒光像素的電子束可沿?zé)晒庀袼亻L度方向在任意點聚焦,這里以相同的三束代表性電子束5b,6b和7b說明。結(jié)果是發(fā)光點可在此像素中精細(xì)位移。
圖3(c)說明了入射至像素級光學(xué)元件2上的光束的尺寸和縱橫比的重要性,此處從后部顯示。在電視顯像管中深度的視覺顯示在分辨率需要方面與視頻信號的亮度或黑白份顯示相比在所需分辨率方面更近似于色度或顏色顯示。據(jù)此我們認(rèn)為,視頻信號中絕大多數(shù)可察覺的細(xì)節(jié)是由圖像的相對高分辨率亮度成份傳送的,其上顯示低分辨率的色度成分。因為在考慮感知顏色時眼睛的要求比考慮感知圖像細(xì)節(jié)時要低得多,所以就有可能在色度上采用更低的分辨率。我們實驗室中的研究表明,眼睛在感知電視圖像深度時也類似地要求不高。
雖然已說過,可視深度的顯示仍是由入射至線性像素級光學(xué)元件的光束的物理運動產(chǎn)生的,而且很明顯,此入射光束的運動范圍越大,影響可視深度的機會就越大。
在圖3(c)中,像素級光學(xué)元件2的高約為寬的三倍。準(zhǔn)直入射光束66a,此處以截面表示,為圓形,直徑約為光學(xué)元件2的寬度。準(zhǔn)直入射光束66b同樣為圓形,但直徑約為光學(xué)元件2長度的1/5。一方面,這使得束66b可比束66a移動一個較大的運動范圍,提供了在結(jié)果圖像中更大范圍可視深度的可能,但另一方面,這是以截面照明光束區(qū)域為代價的,它只有束66a的大約36%。用于保持結(jié)果圖像的相當(dāng)亮度,入射束66b的強度將必須為束66a的大約2.7倍,這種提高是完全可以實現(xiàn)的。
束66c與像素級光學(xué)元件2同寬,但為一水平橢圓,具有束66b的高度,這就是說,只有光學(xué)元件2的1/5高度。這種結(jié)果橢圓截面的照明光束比圓形束66a亮度低,但比較小圓形束66b約亮兩倍。這種設(shè)計很有效,且只比最佳的矩形截面照明光束66d遜色。后者實際上是本發(fā)明最后且最優(yōu)選實施例采用的光束截面。
圖4(a)說明如何將像素級光學(xué)元件2設(shè)置成行陣列,為說明起見畫出了其中幾個,以及如何將它們設(shè)置在照明源的前面,此處畫出的為一優(yōu)選實施例中的陰極射線管10。當(dāng)受控電子束掃描一行像素級光學(xué)元件時,其垂直位移對于每一像素獨立變化,產(chǎn)生一水平掃描線,為說明目的以線15代表,既在像素陣列后以虛線表示,也在左邊橢圓中以實線作分離清楚表示。將會看到,在傳統(tǒng)陰極射線管顯示器中為直線的水平掃描線,對于每一單個像素從掃描中線作一細(xì)微位移,從而產(chǎn)生一圖像,通過改變各個像素到觀察者的距離而包含感知深度的大致分辨率。
經(jīng)驗表明,單個像素級光學(xué)單元之間的微隙間距可降低光學(xué)單元之間的光學(xué)“串音干擾”,從而提高了圖像清晰度,而且這種光學(xué)元件的隔離通過在其間隙中填入黑色不透光材料可得以進(jìn)一步加強。隙間距在0.25mm量級已證明是很成功的,但小到0.10mm的間距也已演示過,作為光學(xué)隔離器作用很好,特別是在注入上述的不透光材料時。
這些像素級光學(xué)元件陣列已通過如下工藝制成,即采用光學(xué)中性粘合劑將各單個光學(xué)元件手工粘接到適當(dāng)陰極射線管的表面。當(dāng)然這種過程很費力,并且由于手工輔助工具精確性的限制而容易產(chǎn)生設(shè)置錯誤。然而,光學(xué)器件陣列通過如下工藝已可很成功地制造,先制造一相反的整個光學(xué)元件陣列的金屬“原?!?,然后將該可用的光學(xué)元件陣列壓印到熱塑性材料上以制成一個“原?!钡摹皦褐啤睆?fù)制品,然而將其整個粘接到陰極射線管的表面。通過壓模對高精細(xì)表面的復(fù)制,由于復(fù)制高精細(xì)大信息量的載體,諸如光盤和致密盤這類需以高精度和低成本在廉價塑料上進(jìn)行典型復(fù)制的載體的技術(shù)需求,近年已形成為一種工藝形式??梢灶A(yù)計,生產(chǎn)大批量制作的像素級光學(xué)元件陣列的優(yōu)選制造技術(shù)仍將是包含熱塑材料的壓模工藝。我們在實驗室中也已成功地通過注模技術(shù)生產(chǎn)了像素級光學(xué)元件陣列。迄今為止,三層不同的像素級光學(xué)三件,每一層代表一不同的光學(xué)單元,已得到成功對準(zhǔn),制成一個三單元微光學(xué)元件陣列。在有些優(yōu)選實施例中,將這些層粘接起來以有助于保持對準(zhǔn),而另一些實施例中,這些層在邊緣處固定而并不粘接在一起。
在將像素級光學(xué)元件設(shè)置于陰極射線或其他發(fā)光裝置表面時,應(yīng)嚴(yán)格保證光學(xué)元件與其下像素的精確對準(zhǔn)。垂直錯位會導(dǎo)致所得圖像中在顯示深度上具有一永久的偏差,而水平錯位會導(dǎo)致三維顯示裝置提供的橫向可視范圍受到限制。而且,通過盡可能減小照明熒光物質(zhì)與光學(xué)元件入射面之間的距離,可提高發(fā)光像素與像素級光學(xué)元件之間的光學(xué)連接。在陰極射線管的環(huán)境中,這意味著光學(xué)元件所附著的管前表面玻璃應(yīng)在保持足夠的結(jié)構(gòu)完整性同時有最小的厚度。在大的陰極射線監(jiān)測器中,此前表面可厚達(dá)8mm,但我們已成功采用了用于特殊構(gòu)造的具有2mm前表面厚度的陰極射線管的這些光學(xué)元件。陰極射線管的一個很成功實施例結(jié)構(gòu)為像素級光學(xué)元件實際是由管的前表面制得。
圖3(b)和4(a)顯示了成像管像素35和像素級直線型光學(xué)單元2的一種大致矩形模式,也即,陣列的行是直線的,并且以上下行進(jìn)行像素與像素的對準(zhǔn)。這種像素及光學(xué)元件模式可產(chǎn)生很易接收的三維圖像,但不應(yīng)認(rèn)為這是本發(fā)明可能的唯一模式。
圖4(b)顯示了像素35的另一種優(yōu)選模式,其中三像素的水平組與其左右組垂直偏位,形成三像素組的“貼瓦”(tiled)模式。此種結(jié)構(gòu)已在實驗室建成,此三像素組,包括一個紅像素35r,一個綠像素35g和一個藍(lán)像互35b。如通常的2維電視顯像管一樣,彩色圖像由對這些組,或這些相同三色像素的“三色組”的相應(yīng)照明形成。每一個三色組中三種色彩的不同順序是可能的,而圖4(b)所示順序為我們實驗室中目前采用的實施例。
圖5說明了在掃描圖像如通常電視圖像中水平掃描線的深度信號的精細(xì)修正。在圖5右上部所示的傳統(tǒng)陰極射線電視或計算機顯示器管中,按動作順序的每一單幅畫面是由電子束水平地逐行向下掃描屏幕形成的,這些掃描線以圖5中四條代表性掃描線17表示。這種非常規(guī)則的掃描是由電視或計算機顯示器的電子線路通過水平掃描線發(fā)生器16進(jìn)行控制的,而信號的亮度或色度成份的不穩(wěn)定變化導(dǎo)致水平掃描線有規(guī)律的從上至下過程的變化。
本發(fā)明以直線水平掃描的精細(xì)位移形式對上述規(guī)律性施加改變以產(chǎn)生深度效果。這種變化通過采用深度信號發(fā)生器18來具體實現(xiàn),其深度信號通過加法器19加入直線水平線中,以產(chǎn)生每一水平掃描線的垂直位置的細(xì)微改變,生成通常與線20類似的線。圖5所示深度信號發(fā)生器是一般性功能的代表;在電視機中,深度信號發(fā)生器為通常的視頻信號解碼器,它通常從接收的視頻信號中提取亮度、色度及時鐘信息,而如下所述其功能現(xiàn)在得以加強,即將以整體類似方式編碼入上述信號的深度信息提取出來。類似地,在計算機中,深度成份發(fā)生器為軟驅(qū)顯示卡,如VGA顯示卡,它通常提供亮度、色度及時鐘信息給計算機顯示器,并將向其同樣提供軟驅(qū)深度信息。
圖6說明了在本發(fā)明另一優(yōu)選實施例中采用透明膠片14向像素級光學(xué)元件2提供受控輸入照明的方式。在此例中,設(shè)置在圖示光學(xué)單元后的膠片部分,除設(shè)計用以允許光進(jìn)入光學(xué)元件所需點的一個透明點外,是不透明的。膠卷以傳統(tǒng)方式從后部照明,但僅有光束5C是以通過膠片上的透明點透過光學(xué)元件2。將會發(fā)現(xiàn),此種情形與圖3中情形相類似,那兒采用陰極射線管中的受控電子束來選擇照明束的位置。所用透明膠片可以為任意尺寸,已實現(xiàn)了采用大致8英寸乘10英寸的透明膠片的實施例。
圖7顯示了采用像素級光學(xué)元件2,其中畫出12個以說明從特殊制備的膠卷13上顯示圖像的方式。光學(xué)陣列11由夾持器12定位保持。膠卷13上的圖像以傳統(tǒng)方式背后照明,結(jié)果圖像通過傳統(tǒng)投影透鏡系統(tǒng),此處以虛線圓22代表,聚焦在陣列11上,它與膠卷13及投影透鏡22在光軸23上共軸。產(chǎn)生的三維圖像可以直接觀看或用作已知型式的三維真實圖像投影機的圖像產(chǎn)生裝置。同樣,產(chǎn)生的三維圖像可作為靜止圖像觀看,或象傳統(tǒng)動畫一樣以相同的幀頻的真實三維動畫順序觀看。在此實施例中,膠卷13上的單個像素應(yīng)比電視顯示所采用的小得多,因為所得像素要經(jīng)過投影放大;攝影膠片電視顯示器具有的優(yōu)越分辨率,很容易容納像素尺寸的這種減小。
圖8顯示了采用兩個攝像鏡頭以決定場景中每個物體的深度的情景,也即,決定場景中任一物體到主攝像鏡頭的距離。待攝景物,此處從上面觀看,用實線矩形24,實線正方形25和實線橢圓26代表,每個都與主攝像鏡頭27具有不同的距離,因而每個在攝影場景中具有不同的深度。采用主攝影鏡頭27從美學(xué)上優(yōu)選角度拍攝圖像的主要細(xì)節(jié)。輔助鏡頭28設(shè)置在離第一鏡頭一定距離處,以傾斜方式對準(zhǔn)景物,固而與主攝影鏡頭同時拍攝相同景物的不同景觀。然后采用公知的幾何三角測量技術(shù)來決定場景中每一物體離主攝影鏡頭的真實距離。
做出這些計算以及產(chǎn)生所得深充信號的一個優(yōu)選方式是在生產(chǎn)后階段進(jìn)行,其中關(guān)于產(chǎn)生深度信號的計算是“脫線”(off-line)作出的,這就是說,它是在圖像拍攝后,且一般是在遠(yuǎn)離圖像拍攝的地點,以與實時攝像速率不相關(guān)的深度信號產(chǎn)生速度,來作出計算。深度信號產(chǎn)生的另一優(yōu)選方式為“實時”作出必要的計算,即基本在圖像生成時。實時產(chǎn)生深度信號的優(yōu)點在于它產(chǎn)生實況(live)三維圖像。然而實時產(chǎn)生的計算需求要遠(yuǎn)遠(yuǎn)大于“脫線”處理的,其中速度可以放慢從而可利用低計算能力,和成本較低。實驗室中進(jìn)行的試驗表明,因為成本及緊湊的電子結(jié)構(gòu)而成為優(yōu)選的實時處理所需計算的方法為,通過采用數(shù)字信號處理器(DSP)用于圖像處理,即數(shù)字圖像處理器(DIP),它們都是專門設(shè)計的,功能窄但速度高的處理器。
由于采用輔助鏡頭28從不同于主攝影鏡頭的角度單獨拍攝物體,此輔助鏡頭一般比主攝影鏡頭的像質(zhì)可以低一些,因而具有低成本。特別對于動畫的應(yīng)用,主攝影鏡頭較貴且采用昂貴膠片,而而輔助鏡頭可以是用于膠片或者視頻型號的低成本鏡頭。因此,與傳統(tǒng)攝影的立體成像技術(shù)相反,其中兩個鏡頭因為都是主攝影鏡頭,所以每個都必須采用昂貴的35mm或70mm膠片,我們的技術(shù)僅需要采用一個高質(zhì)量,高成本鏡頭,因為這兒只有一個主攝影鏡頭。
雖然由不同角度獲得的同一景物的兩個圖像有這種比較分析已證明是很成功的,但也可以通過采用前置的并非固的成像傳感器的主動或被動傳感器來從一景物中獲取深度信號。實驗室中,通過采用一系列商業(yè)上可得的超聲探測器來獲取用于照射景物的超聲輻射的反射信號,我們已成功獲得一個景物的完整的逐個像素的深度分布,我們實驗室中稱作“深度圖”(depth map)。類似地,我們已成功采用掃描紅外探測器來順序獲取用以照射景物的紅外輻射的反射信號。最后,我們在實驗室中已成功進(jìn)行了利用微波輻射作為照射源并利用微波探測器以獲得發(fā)射輻射的實驗;此技術(shù)用于需達(dá)系統(tǒng)中獲得三維圖像會是特別有用的。
圖9(a)說明了從通常二維圖像導(dǎo)出深度信號的基本步驟,從而使將通常包括膠片圖像也包括視頻圖像的二維圖像,處理為三維圖像的成為可能。
在圖9(a)中,在上面圖8中展示的相同系列的三個物體24,25和26在此處從前面看顯示在一顯示器上。在二維顯示器29上,觀察者當(dāng)然看不到深度的任何區(qū)別。
在我們將深度成份加入二維圖像的過程中,首先利用一個視頻數(shù)字化模塊在計算和工作站上將景物數(shù)字化。隨后,利用公知的邊緣探測及其他技術(shù)的物體界定軟件組合,確定所考慮景物中每一單個的物體,從而為改進(jìn)深度可對每一物體單獨處理。在軟件不能自動地充分確定和分離物體時,一個人工編輯器可作出清楚判斷,采用一鼠標(biāo)器,一支光筆、觸摸屏和探針,或類似指向裝置以描出和確定物體。一旦景物被分離成單個物體,人工編輯器就向軟件L為依次確定場景中每一物體到鏡頭的相應(yīng)距離,即表現(xiàn)深度。此過程是完全人為的,很明顯,編輯器部分的較差判斷將導(dǎo)致產(chǎn)生失真的三維場景。
在此過程的下一步,軟件依次掃描場景中的每一像素,并為此像素確定一深度成份。此處理結(jié)果以顯示器30上的深度成份掃描線31來代表,它表示從顯示屏29的中間一行像素獲得的代表性深度信號,掃描線橫貫屏幕上的每一物體。在圖8中所示這些物體的頂視位置與圖9(a)中代表性深度成份掃描線31表現(xiàn)的相應(yīng)深度有關(guān)。
圖9(b)表示用以根據(jù)本方法將深度加入視頻圖像的設(shè)備的連接與工作原理。在此圖中,內(nèi)設(shè)有視頻數(shù)字轉(zhuǎn)換器71的圖像處理計算機工作站70,控制著輸入磁帶錄像機(VTR)72,和輸出磁帶錄像機73,以及一個視頻矩陣轉(zhuǎn)換器74(圖9(b)中控制以短劃線表示,信號流動以實線表示)。視頻數(shù)字轉(zhuǎn)換器根據(jù)工作站的指令通過矩陣轉(zhuǎn)換器接收輸入VTR的一幀視頻信號。此幀信號接著被數(shù)字化,圖9(a)中所述的物體界定過程就施加于生成的數(shù)字場景中了。在對此幀計算深度信號后,伴隨計算的深度成份將此相同幀的信號輸入一個NTSC視頻信號發(fā)生器75,深度成分由NTSC發(fā)生器加入視頻幀信號的視頻頻譜的適當(dāng)位置。生成的深度編碼視頻幀接著寫出在輸出VTR 73上,然后對下一幀重新開始此過程。
關(guān)于此過程在實驗室中對其開發(fā)時出現(xiàn)了幾個主要的要點。第一個要點為,由于深度成分由NTSC發(fā)生器加入,它只插入深度成分而不改變信號的任何其他方面,所以信號的原始圖像部分可無需先對圖像數(shù)字化而寫在輸出VTR上。這就消除了由于對圖像進(jìn)行數(shù)字化再重新轉(zhuǎn)換成模擬形式而產(chǎn)生的視覺衰退,從而發(fā)生的唯一這種衰退為在圖像復(fù)制過程中固有的產(chǎn)生到產(chǎn)生的衰退,這種衰退通過采用播送形式“組分圖像”(component video)的模擬VTR 如M-II或Betacam裝置可減至最低。當(dāng)然,如成像行業(yè)所公知,通過利用全數(shù)字錄像裝置,無論是基于計算機的還是基于磁帶的,在任何產(chǎn)生到產(chǎn)生的過程中都沒有衰退。
第二點為,由于這很大程度上為逐幀處理過程,所以在深度加入時需要稱作“幀校準(zhǔn)”(frame-accurate)VTR或其他記錄裝置。編輯器必須能夠訪問所需的每一單個幀,并可使此經(jīng)處理的幀寫出在輸出磁帶的正確位置上,而只有設(shè)計能訪問每一個別幀(例如,按照SMPTE時鐘碼)的裝置才適合用于此。
第三點為,整個過程可置于計算機控制之下,進(jìn)而可由單個計算機控制面板進(jìn)行操作,這比由幾套分離的控制器操作要方便得多。如果能得到可由計算機控制的播送水平成分VTR或其他記錄裝置,既包括模擬的也包括數(shù)字的,通過采用這種計算機-VTR連接用于耗時的自動倒帶及預(yù)卷,則可實現(xiàn)這種深度加入過程的某些方面的半自動化。
第四點為,應(yīng)賦于軟件一定方面的通常所謂“人工智能”或“機器智能”,以在微觀層面提高深度加入的質(zhì)量。例如,我們在實驗室中已發(fā)展并改進(jìn)了在人面深度加入過程中賦予更大真實性的技術(shù),利用了人面的拓?fù)鋵W(xué),即如下事實,鼻子在臉頰更突出,臉頰逐步向后傾斜至耳朵處,等等,每一特點都有其自身的深度特征。在處理影片或錄像中發(fā)現(xiàn)的大量普通物體時,這有助于降低對編輯器大量輸入的需求(這里采用人面作為例子)。
第五點為,控制軟件可設(shè)置為能以半自動方式工作。這是指,只要場景中的物體保持相對穩(wěn)定,則控制工作站就自動地處理連續(xù)幀而無需由編輯器的附加輸入,從而有助于簡化并加速此處理過程。當(dāng)然,如果新物體進(jìn)入場景,或景觀無規(guī)律變化,此處理就重新需要編輯輸入。我們在實驗室中已發(fā)展并且目前正在改進(jìn)基于人工智能領(lǐng)域的技術(shù),此人工智能根據(jù)對于軟件所知場面中景觀及相應(yīng)物體尺寸的變化來自動計算對于單個物體深度的改變量。
第六點為,當(dāng)輸入及輸出載體為靜止或運動畫畫片時,輸入VTR72,輸出VTR73和視頻矩陣轉(zhuǎn)換器74可分別以一高分辨率圖像掃描器,一數(shù)字?jǐn)?shù)據(jù)開關(guān)和一個高分辨率印像機來代替。此過程的剩余部分與上述圖像處理情況基本相同。在此情況下,利用NTSC發(fā)生器加入深度信號由圖8所示的攝影過程所取代。
第七點為,若工作在全數(shù)字記錄環(huán)境中,如基于計算機的圖像存儲中,則輸入VTR72,輸出VTR 73和視頻矩陣轉(zhuǎn)換器74可全部由計算機的大容量存儲裝置有效代替。這種大容量存儲裝置典型即為磁盤,如我們實驗室中用于基于計算機的編輯工作站上那樣,但它也可以是其他形式的數(shù)字大容量存儲器。在這種全數(shù)字環(huán)境下,利用NTSC發(fā)生器加入深度信號可以避免,而采用向計算機的傳統(tǒng)圖像存儲形式的像素級單元構(gòu)成的深度圖上加入深度信號。
附后的附件A為部分所列軟件的拷貝,用在實驗室條件下,以實現(xiàn)上面照圖9(a)及9(b)所述的改進(jìn)。
圖10說明在這些完善過程中得出的像素級深度顯示技術(shù)在印刷圖像的三維顯示上的應(yīng)用。畫面32為傳統(tǒng)二維照片或印刷圖像。像素級微透鏡(為清楚起見此處放大顯示)的基片33放在二維圖像上,使每一微透鏡具有一不同焦距,從而向觀察者眼睛以不同的表現(xiàn)深度展示此像素。從大比例放大的截面34看,可看到每一微透鏡都具有特殊形狀及光學(xué)特性,從而由其特殊的圖像像素向觀察者提供恰當(dāng)感知的深度。雖然我們實驗室中迄今采用的微透鏡直徑小至1mm,但已進(jìn)行了小于1mm微透鏡的試驗,它表明,此尺寸的透鏡陣列是完全可行的,并將產(chǎn)生具有很高分辨率的三維印刷圖像。
在批量生產(chǎn)時,可以預(yù)料,將采用此處所述的深度信號產(chǎn)生技術(shù)來制作一個壓印原模,以此將給定圖像的大批量低成本微透鏡陣列再次壓印在可印的或熱塑性的材料上,其方式類似于對致密盤的攜帶數(shù)據(jù)表面的壓印或常用于信用卡的大批量復(fù)制的反射全息圖的壓印。此技術(shù)有望實現(xiàn)大規(guī)模,低成本三維印刷的圖像,以用于雜志,報紙及其他印刷載體上。雖然微透鏡的基片33描繪成矩形模式,但其他模式的如同心圓式的微透鏡同樣顯得很有效。
有必要指出,在傳統(tǒng)NTSC視頻信號上的圖像、或亮度載波占據(jù)的視頻寬度顯著大于色度或深度副載波。NTSC視頻圖像的亮度成分具有相當(dāng)高的清晰度,常以“細(xì)鉛筆”畫出的圖畫來表征。另一方面,色度信號為產(chǎn)生電視圖像中可接受的顏色成分只需攜帶相當(dāng)少的信息,常以“寬刷”在高分辨率的黑的圖像畫出“濺射”的顏色來表征。本發(fā)明的深度信號形式上在有限信息量需求方面相對于高分辨率圖像載波來說更接近于顏色信號。
視頻信號控制的關(guān)鍵要素之一為如何將信息編碼在原始信號產(chǎn)生時還不存在的信號中,以及如何做到這一點而不干擾電視接收機的安裝基座或使其失效。圖11表示傳統(tǒng)NTSC視頻信號的能量分布,顯示了畫面或亮度載波36,及色度或顏色信號載波37。圖像頻譜中的所有信號都是有分離頻率間隔的能量載波,此處以分立垂直線代表;頻譜的其余部分空置而沒有使用。由圖11可以看到,彩色NTSC圖像信號的構(gòu)造者成功地將大量添加信息(即顏色)嵌入了生成的信號結(jié)構(gòu),利用了將分離頻率點的信號能量會聚的相同思想,然后將這些點交插在圖像載波的生成能量頻率點之間,以使二者不發(fā)生重疊且不相互干擾。
以同樣的方式,本發(fā)明將更進(jìn)一步的添加信息,以所需深度信號形式,編碼到存在的NTSC視頻信號結(jié)構(gòu)中,它利用了用于色度信號的相同交插方法。圖12說明了此方法,再次顯示了與圖11中相同的亮度載波36及色度副載波37,并加入了深度副載波38。為參考目的,色度副載波占據(jù)了大約1.5MHz的頻寬,中心頻率3.579MHz,而深度副載只占據(jù)大約0.4MHz的頻寬,中心頻率為2.379MHz。這樣,色度和深度副載波,每個交插在亮度載波上,就充分分離而不發(fā)生相互干擾。盡管所述副載波頻率及其占據(jù)的頻寬工作很好,其它情況實際也是可能的。例如,在實驗室進(jìn)行的試驗中,我們成功演示出將深度副載波所需的上述0.4MHz頻寬作顯著降低,對深度信號在其插入NTSC信號之前運用了公知的壓縮技術(shù);在用于驅(qū)動深度顯示成像裝置之前緊接著在放像端進(jìn)行信號提取解壓。同樣,將深度信號加入PAL及SECAM圖像制式的類似方法已在實驗室中試驗過,盡管其結(jié)構(gòu)特性及相關(guān)頻率由于這些圖像信號結(jié)構(gòu)的不同特點而有所改變。在全數(shù)字環(huán)境下,如基于計算機的圖像存儲,存在大量的圖像存儲形式,因而加入用于深度圖存儲的數(shù)位的方法也隨不同形式而改變。
圖13(a)以功能形式說明了傳統(tǒng)電視接收機中典型控制掃描電子束在陰極射線管中垂直偏轉(zhuǎn)的電路系統(tǒng),采用了電視工業(yè)中的常用術(shù)語。雖然某些細(xì)節(jié)可能隨商標(biāo)及型號而有所改變,但關(guān)鍵部分是相同的。
在代表電視接收機傳統(tǒng)設(shè)計的此圖中,目的是產(chǎn)生連續(xù)的且與輸入視頻信號同步的掃描電子束的一次掃描。信號由調(diào)諧器49獲得并由圖像信號中頻放大器50加以放大,然后傳送至視頻檢波器51以提取視頻信號。視頻檢測器51的輸出由檢波輸出放大器52放大,再進(jìn)一步由第一視頻放大器53放大,然后通過延遲線54。
在傳統(tǒng)視頻信號中,有三個主要成分亮度(即明亮程度,或信號的 “黑的”部分);色度(或顏色部分);以及信號的定時部分,以保證每個事件都按正確的平面發(fā)生。在這些成分中,同步信號由同信號分離器55的放大信號分離出來,然后將垂直同步信號在垂直同步轉(zhuǎn)換器56中進(jìn)行轉(zhuǎn)換,提供給垂直掃描發(fā)生器64。此掃描發(fā)生器的輸出提供給陰極射線管的電磁線圈,即熟知的偏轉(zhuǎn)線圈65。正是此偏轉(zhuǎn)線圈引起掃描電子束沿著一條平滑的直線路徑通過陰極射線管的屏幕。
如前面所述,在三維電視顯像管中,此直線電子束路徑的細(xì)微變化通過像素級光學(xué)元件,可產(chǎn)生三維效果。圖13(b)以同樣功能形式說明了必須加入傳統(tǒng)電視中的如下附加電路,用以從適當(dāng)編碼的圖像信號中提取深度成分并將信號的此種深度成分轉(zhuǎn)換成掃描電子束的細(xì)微變化路徑。此圖中,短劃線外面的功能即圖13(a)所示的傳統(tǒng)電視接收機的功能,而短劃線之內(nèi)的功能表示為提取深度成分產(chǎn)生三維效果而需添加的部分。
如圖12中所示,將深度信號編碼到NTSC視頻信號中的方式與色度或顏色信號的編碼基本相同,但比較簡單且在不同頻率處。因為其編碼過程相同,所以包含深度成分的信號,通過采用傳統(tǒng)電視機中在提取前放大彩色信號所采用的相同放大器,即此處表示的第一彩色中頻放大器57,可放大至足以提取的水平。
信號中這種放大的深度成分以與從相同信號中提取編碼顏色信號所采用的相同方式,從視頻信號中提取出來。在此過程中,電視接收機產(chǎn)生一個參考或“標(biāo)準(zhǔn)”(yardstick)信號,其頻率為深度成分所應(yīng)具有的頻率。此信號與這個頻率處實際出現(xiàn)的信號相比較,與“標(biāo)準(zhǔn)”的任何差別即被看作深度信號。這種參考信號由深度門脈沖產(chǎn)生器59產(chǎn)生,并由深度門脈沖限制器58整形至所需水平。形成的純參考信號,由與傳統(tǒng)電視接收機中同步電子束的水平掃描所采用的相同同步信號分離器55,保持與輸入的編碼深度信號的同步。
當(dāng)來自第一彩色中頻放大器57的放大的編碼深度信號與來自深度門脈沖限制器58的參考信號匯合以進(jìn)行比較時,其結(jié)果由選通深度同步放大器63加以放大。此放大信號將包含色彩與深度成分,因而只有深度信號編碼頻率2.379MHz周圍的那些信號才由提取器62提取出來。這就是提取的深度信號,接著由X′TAL輸出放大器61放大至一個有用水平。
在從混合視頻信號中提取出深度成分后,此電路現(xiàn)在必須調(diào)整通過電視屏幕的電子束的平滑水平掃描,以使在所得圖像中能夠顯示深度。為了調(diào)整這種水平掃描,將提取的放大深度信號在深度加法器60中加入傳統(tǒng)電視機周期性產(chǎn)生的標(biāo)準(zhǔn)垂直同步信號,如前面圖13(a)所述。由深度加法器60輸出的調(diào)整垂直同步信號用以在垂直掃描發(fā)生器64中產(chǎn)生電子束的垂直掃描,垂直掃描發(fā)生器64,在傳統(tǒng)電視接收機中,驅(qū)動控制掃描電子束運動的偏轉(zhuǎn)線圈65。最后結(jié)果得到由其通常中心線向上或向下細(xì)微偏移的掃描電子束,通過如前所述精細(xì)改變光在像素級光學(xué)元件上的入射點,在視頻圖像上產(chǎn)生三維效果。
圖14表示實現(xiàn)圖13短劃線框中所示的那些附加功能的電子線路的優(yōu)選實施例。
圖15說明了改變?nèi)肷涞讲煌问降南袼丶壒鈱W(xué)結(jié)構(gòu)的光束位置的一種替代裝置。在這種替代裝置中,像素級光學(xué)結(jié)構(gòu)39具有適當(dāng)?shù)墓鈱W(xué)轉(zhuǎn)換功能,其焦距相對光學(xué)單元39的光軸向外輻射狀增加且關(guān)于其光軸43對稱。準(zhǔn)直成柱狀形式的光束入射到此光學(xué)結(jié)構(gòu)上,準(zhǔn)直光柱的半徑從零到光學(xué)結(jié)構(gòu)的有效工作半徑變化。三束這種可能的柱狀準(zhǔn)直光40,41和42在圖中表示出來,分別產(chǎn)生從前面看的環(huán)狀入射光帶40a,41a和42a,根據(jù)此裝置的特殊光學(xué)轉(zhuǎn)換功能,它們每個將產(chǎn)生一個離觀察者不同明視距離的生成光像素。
圖16以壓縮形式清楚表示,改變單個像素出射光至觀察者的視覺距離的又一種替代裝置。在此圖示中,觀察者眼睛4位于像素級光學(xué)元件前一定距離處。準(zhǔn)直光束入射在傾斜設(shè)置的反射鏡76的不同點上,其中三束由圖示畫出,即光束5,6和7。反射鏡76將入射光束反射至凹面鏡77的傾斜部分,由于凹面鏡的成像特性,呈現(xiàn)出距觀察者不同視覺距離的光束5a,6a和7a,對應(yīng)于輸入光束的前述及標(biāo)記的特殊位置。此凹面鏡可具有多種圓錐截面的數(shù)學(xué)曲面,我們實驗室中已成功采用了雙曲面,拋物面及球面曲面的凹面鏡。在此實施例中,實驗結(jié)果表明,平面的以及曲面的反射鏡都應(yīng)是第一表面變化。
圖17說明在圖16中所示設(shè)置的一個優(yōu)選實施例中,如何將平面反射鏡76及凹面鏡77的像素級結(jié)合設(shè)置在用作照明源的陰極射線管表面上。圖中一個像素的凹面鏡77與相鄰(直接上面)像素的平面鏡結(jié)合在一起,形成一個組合單元78,它設(shè)置在陰極射線管的玻璃前表面8上,其后即為傳統(tǒng)的熒光層9,它在受到投射的準(zhǔn)直電子束的撞擊后發(fā)光以產(chǎn)生光束,此圖中以束5b,6b及7b在不同位置表示上述電子束。對于這三個圖示位置的每一個,以及對于此像素級光學(xué)元件空間界限內(nèi)的任何其他光束位置,點光束將入射至此組件的單一點上,并進(jìn)而在一個對應(yīng)的單一點上呈現(xiàn)給觀察者。至于本發(fā)明的折射實施例,不同于陰極射線的其他光源可以很合適地加以采用。
附錄A
∥3D0105.cpp∥AGENTS OF CHANGE INC.∥Advanced Technology 3-D Retrofitting Controller Software∥Employing Touch Screen Graphical User Interface∥V.01.05∥Includes the following control elemenis#include<dos.h>#include<stdio.h>#include<conio.h>#include<graphics.h>#include<stdlib.h>#include<string.h>#include<iostream.h>#define MOUSE 0×33#define BUTIPRESSED1#define BUT2PRESSED2#define TRUE 1#define FALSE0void ActivMouse(){   ∥activate mouse.   _AX=32;   geninterrupt(MOUSE);}int ResetMouse(){   ∥mouse reset.   _AX=0;   geninterrupt(MOUSE);   return(_AX);}void ShowMouse(){  ∥turn on mouse cursor.  _AX=1;  geninterrupt(MOUSE);}void HideMouse(){   ∥ turn off mouse cursor.   _AX=2;   geninterrupt(MOUSE);}void ReadMouse(int *v,int *h,int *but){  int temp;  _AX=3;  geninterrupt(MOUSE);   ∥ which button pressed1=left,2=right,3=both   temp=_BX;   *but=temp;<!-- SIPO <DP n="19"> --><dp n="d19"/>  ∥horizontal coordinates.  *h=_CX;  ∥vertical coordinates.  *v=_DX;}class Button∥ this class creates screen buttons capable of being displayed ratsed∥ or depressed,Labels displayed on the buttons change colour when∥ the button is depressed.{public;   int button_centrex,button_centrey,button_width,button_height;   int left,top,right,bottom,text_size,text_flelds,lfont;   char button_text1[40],buttton_text2[40];   unsigned upattern;∥ button_centrex,button_centrey is the centre of the button placement.∥ button_width and button_height are the dimensions of the button in pixels.∥ button_text is the label on the button.∥ text_size is the text size for settextstyle().   iht mouseX.mouseY.mouseButtont;   int oldMouseX,oldMouseY;   int buttonl Down,button2Down;   int pressed;   Button(int x,int y,int width,int height,int tfields,char *btext1,char *btext2,int tsize,int f)   ∥this constructor initializes the button variables.   {   button_centrex=x;   button_centrey=y(tǒng);   button_width=width;   button_height=height;   strcpy(buttton_text1,btext1);   strcpy(button_text2,btext2);   text_size=tsize;   text_fields=tfields;   lfont=f;   left=button_centrex-buttton_width/2;   top=button_centrey-button_height/2;   right=button_centrex+button_width/2;   bottom=buttton_centrey+button_height/2;   oldMouseX=0;oldMouseY=0;   button1Down=FALSE;   button2Down=FALSE;   pressed=FALSE;   }  void up()  ∥ draws a raised button and prints the required label on it.  {   setcolor(5);   setlinestyle(SOLID_LINE,upattern,NORM_WIDTH);   setfillstyle(SOLID_FILL.LIGHTGRAY);   bar3d(left,top,right,bottom,O,O);   setcolor(WHITE);   setlinestyle(SOLID_LINE,upattern,THICK_WIDTH);<!-- SIPO <DP n="20"> --><dp n="d20"/>  line(left+2,bottom-1,left+2,top+1);  line(left+1,top+2,right-1,top+2);  setcolor(DARKGRAY);  setlinestyle(SOLID_LINE,upatttern,NORM_WIDTH);  line(left+4,bottom-3,right-l,bottom-3);  line(left+3,bottom-2,right-1,bottom-2);  line(left+2,bottom-1,right-1,bottom-l);  line(right-3,bottom-1,right-3,top+4);  line(right-2,bottom-1,right-2,top+3);  line(right-1,bottom-1,right-1,top+2);   ∥ put the required text in the button   setcolor(5);   settextjustify(CENTER TEXT,CENTER TEXT);   settextstyle(lfont,HORIZ DIR,text size);∥ cout<<button_text2<<endl;   if(text_fields==1)   outtextxy(button_centrex,button_centrey-4*(float(button_height)/50).button_text1);   else   {   outtextxy(button_centrex,button_centrey-13*(float(button height)/50).button_text1);   outtextxy(button_centrex,button_centrey+9*(float(button_height)/50).button_text2);   }   pressed=FALSE;   }  void down()  ∥ draw a depressed button and prints the required label on it.   {   setcolor(5);   setlinestyle(SOLID_LINE,upattern,NORM WIDTH);   setfillstyle(SOLID_FILL,DARKGRAY);   bar3d(left,top,right,bottom,0,0);   setcolor(5);   sethnestyle(SOLID_LINE,upattern,THICK_WIDTH);   line(left+2,bottom-1,left+2,top+1);   line(left+1,top+2,right-1,top+2);   setcolor(LIGHTGRAY);   setlinestyle(SOLID_LINE,upattern,NORM_WIDTH);   line(left+4,bottom-3,right-1,bottom-3);   line(left+3,bottom-2,right-1,bottom-2);   line(left+2,bottom-1,right-1,bottom-1);   line(right-3,bottom-1,right-3,top+4);   line(right-2,bottom-1,right-2,top+3);   line(right-1,bottom-1,right-1,top+2);   ∥put the required text in the button.   setcolor(WHITE);   settextjustify(CENTER_TEXT,CENTER_TEXT);   settextstyle(lfont,HORIZ_DIR,text_size);∥ cout<<button text2<<endl;   if(text_fields==1)   outtextxy(button_centrex,button_centrey-4*(float(buttton_heitht)/50,).button_textl);   else   {   outtextxy(button_centrex,button_centrey-13*(float(button_height)/50,).button_textl);   outtextxy(button_centrex,buttion_centrey+9*(float(button_height)/50,).button_text2);   }<!-- SIPO <DP n="21"> --><dp n="d21"/>   pressed=TRUE;   }  int touched()  ∥determines whether a button has been touched,and returns  ∥TRUE for yes,and FALSE for no,Touching is emulated  ∥by a mouse click.   {   int temp;   _AX=3;   geninterrupt(MOUSE);  ∥which button pressed1=left,2=right,3=both.   temp=_BX;   mouseButton=temp;  ∥horizontal coordinates  mouseX=_CX;  ∥ vertical coordinates  mouseY=_DX;  if (mouseButton&amp;BUTIPRESSED)  {   button1 Down=TRUE;   return0;  }  else if(button1 Down)  ∥if button l was down and is now up,it was clicked!   {  ∥check whether the mouse is positioned in the button   if((((mouseX-left)*(mouseX-right))<0)&amp;&amp;(((mouseY-top)*(mouseYbottom))<0))  ∥if this evaluates as TRUE then do the following.   {   button 1 Down=FALSE;   return 1;   }   button 1 Down=FALSE;   return 0;   }   }};∥ XXXXXXXXXXXXXXXXXXX M A I N XXXXXXXXXXXXXXXXXXXXXvoid main(){∥this is the system main.int Page_1_flag,Page_2_flag,Page_3_flag,Page_4_flag,Page_5_flag;int Page_6_flag,Page_7_flag,Page_8_flag,Page_9_flag,Page_10_flag;char which;∥ initialize the graphics systemint gdriver=DETECT,gmode,errorcode;initgraph(&amp;gdriver,&amp;gmode,"c\\borlandc\\bgi");∥ read the result of initialization.errorcode=graphresult();<!-- SIPO <DP n="22"> --><dp n="d22"/>if(errorcode!=grOk){∥an error occurred.   printf("Graphics error%s\n",grapherrormsg(errorcode));   printf("Press any key to hal;");   getch();   exit(I);}∥if(!ResetMouse())∥{∥ printf("No Mouse Driver");∥}∥ set the current colours and line sryle.∥ set BLACK(normally palette 0)to palette 5(normally MAGENTA)∥ to correct a colour setting problem inate to C++setpalette(5.BLACK);∥ activate the mouse to emulate a touch screen∥ActivMouse();∥ShowMouse();∥ construct and initialize buttonsButton logo(getmaxx()/2,100,260,130,1,"(AOCI LOGO)","",4,1);Button auto_controll(200,400,160,50,2,"AUTO","CONTROL",2,1);Button manual_controll(400,400,160,50,2,"MANUAL","CONTROL",2,1);Button mutel(568,440,110,50,1,"MUTE","",4,1);∥Button proceed(getmaxx()/2,440,160,50,1,"PROCEED","",4,1);Button c_vision(getmaxx()/2,350,450,100,1,"3-D RETRO","",8,1);Button main_menu(245,20,460,30,1,"M A I N M E N U","",2,1);Button time_date2(245,460,460,30,1,"Date TimeElapsed ","",2,1);Button video_screen(245,217,460,345,1,"","",4,1);Button video_messagel(245,217,160,50,2,"Video Not,"Detected",2,1);Button auto_onoff2(555,20,130,30,2,"AUTO CONTROL","ON/OFF",5,2);Button manual_control2(555,60,130,30,1,"MANUAL CONTROL","",5,2);Button name_tags2(555,100,130,30,1,"OBJECT TAGS","",5,2);Button voice_tags2(555,140,130,30,2,"TRIANGULATE/","DIST,CALC",5,2);Button custom_session2(555,180,130,30,1,"CUSTOM SESSION","",5,2);Button memory_traming2(555,220,130,30,1,"MEMORY FRAMING","",5,2);Button remote_commands2(555,260,130,30,2,"REMOTE ENDS","COMMANDS",5,2);Button av_options2(555,300,130,30,2,"AUDIO/VISUAL","OPTIONS",5,2);Button codec_control2(555,340,130,30,1,"CODEC CONTROL","",5,2);Button mcu_control2(555,380,130,30,1,"MCU CONTROL","",5,2);Button dial_connects2(555,420,130,30,2,"DIAL-UP","CONNECTIONS",5,2);Button mute2(555,460,130,30,1,"MUTE","",5,2);Button ind_id3(245,20,460,30,1,"PERSONAL IDENTIFICATION","",2,1);Button frame_cam3(555,20,130,30,1,"FRAME CAMERA","",5,2);Button cam_preset3(555,60,130,30,1,"CAMERA PRESET","",5,2);Button autofollow3(555,180,130,30,1,"AUTOFOLLOWING","",5,2);Button return3(555,420,130,30,2,"RETURN TO","LAST MENU",5,2);Button touch_face3(130,418,230,35,2,"DEFINE AN OBJECT","AND THEN TOUCH",5,2);Button type_id3(308,418,105,35,2,"ACQUIRE","OBJECT",5,2);Button write_id3(423,418,105,35,2,"LOSE","OBJECT",5,2);Button cancel3(555,340,130,30,1,"CANCEL CHOICE","",5,2);Button keyboard(245,375,450,200,1,"(Keyboard)","",2,1);Button writing_space(245,425,450,100,1,"(Writing Space)","",2,1);Button typing_done(555,260,130,30,2,"TYPE AND THEN","PRESS HERE",5,2);Button writing_done(555,260,130,30,2,"WRITE AND THEN","PRESS HERE",5,2);Button dial_connects6(getmaxx()/2,20,604,30,1,"DLAL-UP CONNECTIONS","",2,1);Button directory6(getmaxx()/2,60,300,30,1,"DIRECTORY","",2,1);Button manual_dialing6(57,420,84,30,2,"MANUAL","DIALING",5,2);Button line_16(151,420,84,30,1,"LINE 1","",5,2);<!-- SIPO <DP n="23"> --><dp n="d23"/>Button line_26(245,420,84,30,1,"LINE 2","",5,2);Button dial_tone6(339,420,84,30,1,"D1AL TONE","",5,2);Button hang_up6(433,420,84,30,1,"HANG UP","",5,2);Button scroll_up6(104,260,178,30,1,"SCROLL DIRECTORY UP","",5,2);Button scroll_down6(292,260,178,30,1,"SCROLL DIRECTORY DOWN","",5,2);Button dial_this6(198,300,84,30,2,"DIAL THIS","NUMBER",5,2);Button add_entry6(104,340,178,30,1,"ADD AN ENTRY","",5,2);Button delete_entry6(292,340,178,30,1,"DELETE AN ENTRY","",5,2);Button keypad6(505,320,230,151,1,"(Keypad)","",2,1);Page_1;∥ this is the opening screen∥ set the current fill style and draw the background   setfillstyle(INTERLEAVE FILL,DARKGRAY);   bar3d(0,0,getmaxx(),getmaxy(),0,0);   logo,up();   c_vision,up();∥ proceed,up();∥ auto_controll,up();∥ manual_controll,up();   mutel,up();   settextstyle(TRIPLEX FONT,HORIZ_DIR,2);   outtextxy(getmaxx()/2,190,"(C)1993-1995 AGENTS OF CHANGE INC,");   settextstyle(TRIPLEX_FONT,HORIZ_DIR,4);   outtextxy(getmaxx()/2,235,"WELCOME");   outtextxy(getmaxx()/2,265,"TO");   Page_1_flag=TRUE;while(Page_1_flag){∥ temporary keypad substitute for the touch screenwhich=getch();  if(which==‘1’)  {  if (!c_vision.pressed )   {   c_vision down();   goto Page_2;   }   else c_vision,up();  }  if(which==‘2’)  {  if(!mutel,pressed)mutel,down();  else mutel,up();  }if(which==‘S’)Page_1_flag=FALSE;}goto pgm_terminate;Page_2;∥ this is the main menu. setfillstyle(INTERLEAVE_FLLL,DARKGRAY);<!-- SIPO <DP n="24"> --><dp n="d24"/>  bar3d(0,0,getmaxx(),getmaxy(),0,0);  main_menu,up();  video_screen,up();  video_messagel,down();  time_date2,up();  auto_onoff2,up();  manual_control2,up();  name_tags2,up();  voice_tags2,up();  custom_session2,up();  memory_framing2,up();  remote_commands2,up();  av_options2,up();  codec_control2,up();  mcu_control2,up();  dial_connects2,up();  mute2,up();  Page_2_flag=TRUE;while(Page_2_flag){∥ temporary keypad substitute for the touch screenwhich=getch();   if(which==‘1’)   {  if(!auto_onoff2,pressed)  {   auto onoff2 down();  }   else auto_onoff2,up();   }   if(which==‘2’)   {  if(!manual_control2,pressed)manua_control2,down();  else manual_control2,up();   }   if(which==‘3’)   {   if(!name_tags2,pressed)   {   name_tags2,down();   goto Page_3;   }   else name_tags2,up();  }  if(which==‘4’)  {   if(!voice_tags2,pressed)   {   voice_tags2,down();   goto Page_3;   }   else voice_tags2,up();  }  if(which==‘5’)  {<!-- SIPO <DP n="25"> --><dp n="d25"/>   if (!custom_session2,pressed)custom session2,down();  else custom_session2,up();  }  if(which==‘6’)  {   if(!memory_framing2 pressed)   {   memory_framing2,down(),   goto Page_3;   }   else memory_framing2 up();  }  if(which==‘7’)  {   if(!remote_commands2,pressed)remote commands2.down()   else remote commands2,up();  }  if(which==‘8’)  {   if(!av options2,pressed) av_options2,down();   else av_options2,up();  }  if(which==‘9’)  {   if(!codec_control2,pressed)codec_control2,down();   else codec_control2,up();  }  if(which==‘a(chǎn)’)  {    if(!mcu_control2,pressed)mcu control2,down();   else mcu_control2,up();  }  if(which==‘b’)  {   if(!dial_connects2,pressed)  {  dial_connecis2,down();  goto Page_6;  }   else dial_connects2,up();  }  if(which==‘c’)  {   if(!mute2,pressed)mute2,down();   else mute2,up();  }if(which==‘S’)Page_2_flag=FALSE;}goto pgm_terminate;Page_3;∥this is the first"individual identification"menu,∥and includes the step into nametags,<!-- SIPO <DP n="26"> --><dp n="d26"/>  setfillstyle(INTERLEAVE_FILL.DARKGRAY);  bar3d(0,0,getmaxx(),getmaxy(),0,0);  ind_id3,up();  video_screen,up();  video_messagel,down();  time_date2,up();  frame_cam3,up();  cam_preset3,up();  name_tags2,up();  voice_tags2,up();  autofollow3,up();  return3,up();  mute2,up();  Page_3_flag=TRUE;while(Page_3_flag){∥ temporary keypad substitute for the touch screenwhich=getch();   if(which==‘1’)   {  if(!frame_cam3,pressed)  {   frame_cam3,down();   }  else frame_cam3,up();  }    if(which==‘2’)   {  if(!cam_preset3,pressed)cam_preset3,down();  else cam_preset3,up();   }   if(which==‘3’)   {  if(!name_tags2,pressed)  {   name_tags2,down();   touch_face3,up();  type_id3,up();  write_id3,up();  cancel3,up();   type_or_write;   which=getch();   ∥the cancel button has been pressed   if(which==‘9’)goto Page_3;   ∥type nametags,   if(which==‘x’)goto Page_4;   ∥write nametags,   if(which==‘y’)goto Page_5;   goto type_or write;  }   else name tags2,up();  }  if(which=‘4’)  {<!-- SIPO <DP n="27"> --><dp n="d27"/>   if(!voice_tags2,pressed)voice_tags2,down();∥goto Page_4;  else voice_tags2,up(); }  if(which==‘5’) {   if(!autofollow3,pressed)autofollow3,down();∥ goto Page_4;   else autofollow3,up();  }   if(which==‘b’)  {   if(!return3,pressed)return3 down();   goto Page_2;  }   else return3,up();  if(which==‘c’)  {   if(!mute2,pressed)mute2,down();   else mute2,up();  }if(which==‘S’)Page_3_flag=FALSE;}goto pgm_terminate;Page_4;∥ this is the nametags typing page   setfillstyle(INTERLEAVE_FILL,DARKGRAY);   bar3d(0,0,getmaxx(),getmaxy(),0,0);   ind_id3,up();   video_screen,up();   video_messagel,down();   frame_cam3,up();   cam_preset3,up();   name_tags2,down();   voice_tags2,up();   autofollow3,up();   return3,up();   mute2,up();   keyboard,up();   typing_done,up();   Page_4_flag=TRUE;while(Page_4_flag){∥ temporary keypad substitute for the touch screenwhich=getch();   if(which==‘7’)   {  if(!typing_done,pressed)typing_done,down();  goto Page_3;   }<!-- SIPO <DP n="28"> --><dp n="d28"/>   else typing_done,up();   if(which==‘b’)   {   if(!return3,pressed)return3,down();   goto Page_3;  }   else return3,up();  if(which==‘c’)  {   if(!mute2,pressed)mute2,down();   else mute2,up();  }if(which==‘S’)Page_4_flag=FALSE;}goto pgm_terminate;Page 5;∥ this is the nametags writing page   setfillstyle(INTERLEAVE_FILL.DARKGRAY);   bar3d(0,0,getmaxx(),getmaxy(),0,0);   ind_id3,up();   video_screen,up();   video_messagel,down();   frame_cam3,up();   cam_preset3,up();   name_tags2,down();   voice_tags2,up();   autofollow3,up();   return3,up();   mute2,up();   writing_space,up();   writing_done,up();   Page_5_flag=TRUE;while(Page_5_flag){∥ temporary keypad substitute for the touch screen.which=getch();   if(which==‘7’)   {if(!typing_done,pressed)typing_done,down();  goto Page_3;   }  else typing_done,up();   if(which==‘b’)   { if(!return3,pressed)return3,down();  goto Page_3;   }   else return3,up();<!-- SIPO <DP n="29"> --><dp n="d29"/>  if(which==‘c’)  {   if(!mute2 pressed)mute2 down();   else mute2,up();  }   if(which==‘S’)Page_5_flag=FALSE;  }  goto pgm_terminate;  Page_6;  ∥this is the connections dialing and directory maintenance page   setfillstyle(INTERLEAVE_FILL.DARKGRAY);   bar3d(0,0,getmaxx(),getmaxy(),0,0);   dial_connects6,up();   directory6,up();   keypad6,up();   scroll_up6,up();   scroll_down6,up();   dial_this6,up();   add_entry6,up();   delete_entry6,up();   manual_dialing6,up();   line_16,up();   line_26,up();   dial_tone6,up();   hang_up6,up();   return3,up();   mute2,up();   Page_6_flag=TRUE;while(Page_6_flag){∥ temporary keypad substitute for the touch screenwhich=getch();   if(which==‘b’)  {   if(!return3,pressed)   {   return3 down();   goto Page_2;  }   }   else return3,up();    if(which==‘c’)   {   if(!mute2,pressed)mute2,down();   else mute2,up();   }   if(which==‘S’)Page_6_flag=FALSE;   }   goto pgm_terminate;   pgm_ terminate;   getch();<!-- SIPO <DP n="30"> --><dp n="d30"/>∥ this is the closing sequenceclosegraph();}<!-- SIPO <DP n="31"> --><dp n="d31"/>/****************************************//* ARPROCES.H *//*Image Processing Header File *//* Area Processing Functions *//* written in Turbo C 2.0 *//****************************************//* Area Process Function Prototypes */CompletionCode Convolution(BYTE huge *InImage,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   short *Kernel,unsigned KernelCols,   unsigned KernelRows,unsigned Scale,   unsigned Absolute,BYTE huge * * OutImageBufPtr);CompletionCode RealConvolution(BYTE huge *InImage,   unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   double *Kernel,unsigned KernelCols,   unsigned KernelRows,unsigned Scale,   unsigned Absolute,BYTE huge * * OutImageBufPtr);CompletionCode Median Filter(BYTE huge *InImage,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   unsigned NeighborhoodCols,unsigned NeighborhoodRows,   BYTE huge * * OutlmageBufPtr);CompletionCode SobelEdgeDet(BYTE huge* InImage,  unsigned Col,unsigned Row,  unsigned Width,unsigned Height,  unsigned Threshold,unsigned Overlay,  BYTE huge * * OutlmageBufPtr);<!-- SIPO <DP n="32"> --><dp n="d32"/>/****************************************//*ARPROCES.C *//*Image Processing Code *//*Area Processing Functions *//* written in Turbo C 2.0 *//****************************************/#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<dos.h>#include<alloc.h>#include<process.h>#include<math.h>#include<graphics.h>#include"misc.h"#include"pcx.h"#include"vga.h"#include"imagesup.h"#include"arprocess.h"/*Integer Convolution Function*/CompletionCode Convolution(BYTE huge *InImage,unsigned Col,unsigned Row,  unsigned Width,unsigned Height,  short*Kernel,unsigned KernelCols,  unsigned KernelRows,unsigned Scale,  unsigned Absolute,BYTE huge * * OutlmageBufPtr){register unsigned ColExtent,RowExtent;register unsigned ImageCol,ImageRow,KernCol,KernRow;unsigned ColOffset,RowOffset,TempCol,TempRow;BYTE huge *OutputlmageBuffer;long Sumshort *KernelPtr;if(ParameterCheckOK(Col,Row,Col+Width,Row+Height,"Convolution")){  /* Image must be at least the same size as the kernel */  if(Width>=KernelCols &amp;&amp; Height>=KernelRows){  /* allocate far memory buffer for output image */  OutputlmageBuffer=(BYTE huge*)  farcalloc(RASTERSIZE,(unsigned long)sizeof(BYTE));  if(OutputImageBuffer==NULL)  {   restorecrtmode();   printf("Error Not enough memory for convolution output buffer\n");   return(ENoMemory);  }   /*Store address of output image buffer*/   *OutImageBufPtr=OutputImageBuffer;   /*   Clearing the output buffer to white will show the   boarder areas not touched by the convolution,It also<!-- SIPO <DP n="33"> --><dp n="d33"/>  provides a nice white frame for the output image  */  ClearImageArea(OutputImageBuffer.MINCOLNUM,MINROWNUM,  MAXCOLS.MAXROWS.WHITE);  ColOffset=Kernel Cols/2;  RowOffset=KernelRows/2;  /*Compensate for edge effects*/  Col+=ColOffset;  Row+=RowOffset;  Width-=(KernelCols-1);  Height-=(KernelRows-1);  /*Calculate new range of pixels to act upon*/  ColExtent=Col+Width;  RowExtent=Row+Height;  for(ImageRow=Row;ImageRow<RowExtent;ImageRow++)  {   TempRow=ImageRow-RowOffset   for(ImageCol=Col;ImageCol<ColExtent;ImageCol++)   {  TempCol=ImageCol-ColOffset;  Sum=OL;  KernelPtr=Kernel;  for(KernCol=0;KernCol<KernelCols;KernCol++)   for(KernRow=0;KernRow<KerrnelRows;KernRow++)   Sum+=(GetPixelFromImage(InImage,   TempCol+KernCol,TempRow+KernRow)*   (*KernelPtr++));  /*If absolute value is requested*/  if(Absolute)   Sum=labs(Sum);   /*Summation performed,Scale and range Sum*/   Sum>>=(long)Scale;   Sum=(Sum<MINSAMPLEVAL)?MINSAMPLEVAL;Sum;   Sum=(Sum>MAXSAMPLEVAL)?MAXSAMPLEVAL;Sum;   PutPixelInImage(OutputlmageBuffer,ImageCol,ImageRow,(BYTE)Sum);  }    }  }else   return(EKernelSize);}return(NoError);}/*Real Number Convolution Function,This convolution function isonly used when the kernel entries are floating point numbersinstead of integers,Because of the floating point operationsenvolved,this function is substantially slower than the alreadyslow integer version above.*/CompletionCode RealConvolution(BYTE huge *InImage,   unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   double *Kernel,unsigned KernelCols,<!-- SIPO <DP n="34"> --><dp n="d34"/>   unsigned KernelRows,unsigned Scale,   unsigned Absolute,BYTE huge **OutImageBufPtr){  register unsigned ColExtent,RowExtent;  register unsigned ImageCol,ImageRow,KernCol,KernRow;  unsigned ColOffset,RowOffset,TempCol,TempRow;  BYTE huge*OutputImageBuffer;  double Sum  double *KernelPtr;  if(ParameterCheckOK(Col,Row,Col+Width,Row+Height,"Convolution"))  {  /*Image must be at least the same size as the kernel*/  if(Width>=KernelCols &amp;&amp; Height>=KernelRows)  {   /*allocate far memory buffer for output image*/   OutpugImageBuffer=(BYTE huge*)   farcalloc(RASTERSIZE,(unsigned long)sizeof(BYTE));   if(OutputImageBuffer==NULL)   {  restorecrtmode();  printf("Error Not enough memory for convolution output buffer\n");  return(ENoMemory);   }   /*Store address of output image buffer*/   *OutImageBufPtr=OutputImageBuffer;   /*   Clearing the output buffer to white will show the   boarder areas not touched by the convolution,It also   provides a nice white frame for the output image,   */   ClearImageArea(OutputImageBuffer,MINCOLNUM,MINROWNUM,   MAXCOLS,MAXROWS WHITE);   ColOffset=KernelCols/2;   RowOffset=KernelRows/2;   /*Compensate for edge effects*/   Col+=ColOffset;   Row+=RowOffset;   Width-=(KemelCols-1);   Height-=(KemelRows-1);   /*Calculate new range of pixels to act upon*/   ColExtent=Col+Width;   RowExtent=Row+Height;   for(ImageRow=Row;ImageRow<RowExtent;ImageRow++)   {  TempRow=ImageRow-RowOffset;  for(ImageCol=Col;ImageCol<ColExtent;ImageCol++)  {   TempCol=ImageCol-ColOffset;   Sum=0,0;   KernelPtr=Kernel;   for(KernCol=0KernCol<KernelColsKernCol++)   for(KernRow=0KernRow<KernelRowsKernRow++)   Sum+=(GetPixelFromImage(InImage,   TempCol+KernCol,TempRow+KernRow)*<!-- SIPO <DP n="35"> --><dp n="d35"/>   (*KernelPtr++));   /*If absolute value is requested*/   if(Absolute)   Sum=fabs(Sum);   /*Summation performned,Scale and range Sum*/   Sum/=(double)(1<<Scale);   Sum=(Sum<MINSAMPLEVAL)?MINSAMPLEVAL;Sum;   Sum=(Sum>MAXSAMPLEVAL)?MAXSAMPLEVAL;Sum;   PutPixelInImage(OutputImageBuffer,ImageCol,ImageRow,(BYTE)Sum);  }   }  }  else   return(EKemelSize);}return(NoError);}/*Byte compare for use with the qsort library function callin the Median filter function.*/int ByteCompare(BYTE*Entry1,BYTE*Entry2){  if(*Entryl<*Entry2)   return(-1);  else if(*Entryl>*Entry2)   return(1);  else   return(0);}CompletionCode MedianFiter(BYTE huge *InImage,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   unsigned NeighborhoodCols,unsigned NeighborhoodRows,   BYTE huge * * OutImageBufPtr){  register unsigned ColExtent,RowExtent;  register unsigned ImageCol,ImageRow,NeighborCol,NeighborRow;  unsigned ColOffset,RowOffset,TempCol,TempRow,Pixellndex;  unsigned TotalPixels,MedianIndex;  BYTE huge *OutputImageBuffer;  BYTE *PixelValues;  if(ParameterCheckOK(Col,Row,Col+Width,Row+Height,"Median Filter"))  {  /*Image must be at least the same size as the neighborhood*/  if(Width>=NeighborhoodCols &amp;&amp; Height>=NeighborhoodRows)  {  /*allocate far memory buffer for output image*/  OutputImageBuffer=(BYTE huge*)   farcalloc(RASTERSIZE,(unsigned long)sizeof(BYTE));  if(OutputImageBuffer==NULL)  {<!-- SIPO <DP n="36"> --><dp n="d36"/>restorecrtmode();pnintf("Error Not enough memory for median filter output buffer\n");return(ENoMemory);}/*Store address of output image buffer*/*OutImageBufPtr=OutputImageBuffer;/*Clearing the output buffer to white will show theboarder areas not touched by the median filter.It alsoprovides a nice white frame for the output image.*/ClearImageArea(OutputlmageBuffer,MINCOLNUM,MINROWNUM,  MAXCOLS,MAXROWS,WHITE);/*Calculate border pixel to miss*/ColOffset=NeighborhoodCols/2;RowOffset=NeighborhoodRows/2;/*Compensate for edge effects*/Col+=ColOffset;Row+=RowOffset;Width-=(NeighborhoodCols-1);Height-=(NeighborhoodRows-1);/*Calculate new range of pixels to act upon*/ColExtent=Col+Width;RowExtent=Row+Height;TotalPixels=(NeighborhoodCols*NeighborhoodRows);MedianIndex=(NeighborhoodCols*NeighborhoodRows)/2;/*allocate memory for pixel buffer*/PixelValues=(BYTE*)calloc(TotalPixels,(unsigned)sizeof(BYTE));if(PixelValues==NULL){restorecrtmode();printf("Error Not enough memory for median filter pixel buffer\n");return(ENoMemory);}for(ImageRow=Row;ImageRow<RowExtent;ImageRow++){TempRow=ImageRow-RowOffset;for(ImageCol=Col;ImageCol<ColExtentImageCol++){  TempCol=ImageCol-ColOffset;  PixelIndex=0;  for(NeighborCol=0;NeighborCol<NeighborhoodCols;NeighborCol++)  for(NeighborRow=0;NeighborRow<NeighborhoodRows;NeighborRow++)   PixelValues[PixelIndex++]=  GetPixelFromImage(InImage,TempCol+NeighborCol,   TempRow+NeighborRow);  /*  Quick sort the brightness values into ascending order  and then pick out the median or middle value as  that for the pixel.  */  qsort(PixelValues,TotalPixels,sizeof(BYTE),ByteCompare);<!-- SIPO <DP n="37"> --><dp n="d37"/>   PutPixelInlmage(OutputImageBuffer,ImageCol.ImageRow,  PixelValues[MedianIndex]);   }   }}else   renurn(EKemelSize);}free(PixelValues);/*give up the pixel value buffer*/return(NoError);}/*Sobel Edge Detection Function*/CompletionCode SobelEdgeDet(BYTE huge *InImage,   unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   unsigned Threshold,unsigned Overlay,   BYTE huge **OutImageBufPtr){register unsigned ColExtent,RowExtent;register unsigned ImageCol,ImageRow;unsigned PtA,PtB,PtC,PtD,PtE,PtF,PtG,PtH,PtI;unsigned LineAEIAveAbove,LineAEIAveBelow,LineAEIMaxDif;unsigned LineBEHAveAbove,LineBEHAveBelow,LineBEHMaxDif;unsigned LineCEGAveAbove,LineCEGAveBelow,LineCEGMaxDif;unsigned LineDEFAveAbove,LineDEFAveBelow,LineDEFMaxDif;unsigned MaxDif;BYTE huge*OutputImageBuffer;if(ParameterCheckOK(Col,Row,Col+Width,Row+Height,"Sobel Edge Detector")){/*allocate far memory buffer for output image*/OutputImageBuffer=(BYTE huge*)  farcalloc(RASTERSIZE,(unsigned long)sizeof(BYTE));if(OutputImageBuffer==NULL){  restorecrtmode();  printf("Error Not enough memory for Sobel output buffer\n");  return(ENoMemory);}/*Store address of output imagge buffer*/*OutImageBufPtr=OutputImageBuffer;/*Clearing the output buffer*/ClearImageArea(OutputImageBuffer,MINCOLNUM,MINROWNUM,   MAXCOLS,MAXROWS,BLACK);/*Compensate for edge effects of 3×3 pixel neighborhood*/Col+=1;Row+=1;Width-=2;Height-=2;/*Calculate new range of pixels to act upon*/<!-- SIPO <DP n="38"> --><dp n="d38"/>ColExtent=Col+Width;RowExtent=Row+Height;for(ImageRow=Row;ImageRow<RowExtent;ImageRow++)  for(ImageCol=Col;ImageCol<ColExtent;ImageCol++)  {  /*Get each pixel in 3×3 neighborhood*/  PtA=GetPixelFromImage(InImage,ImageCol-1,ImageRow-1);  PtB=GetPixelFromImage(InImage,ImageCol,ImageRow-1);  PtC=GetPixelFromImage(InImage,ImageCol+1,ImageRow-1);  PtD=GetPixelFromImage(InImage,imageCol-1,ImageRow);  PtE=GetPixelFromImage(InImage,ImageCol,ImageRow);  PtF=GetPixelFromImage(InImage,ImageCol+1,ImageRow);  PtG=GetPixelFromImage(InImage,ImageCol-1,ImageRow+1);  PtH=GetPixelFromImage(InImage,ImageCol,ImageRow+1);  PtI=GetPixelFromImage(InImage,ImageCol+1,ImageRow+1);  /*  Calculate average above and below the line  Take the absolute value of the difference  */  LineAEIAweBelow=(PtD+PtG+PtH)/3;  LineAEIAveAbove=(PtB+PtC+PtF)/3;  LineAEIMaxDif=abs(LineAELAveBelow-LineAEIAveAbove);  LineBEHAveBelow=(PtA+PtD+PtG)/3;  LineBEHAveAbove=(PtC+PtF+PtI)/3;  LineBEHMaxDif=abs(LineBEHAveBelow-LineBEHAveAbove);  LineCEGAveBelow=(PtF+PtH+PtI)/3;  LineCEGAveAbove=(PtA+PtB+PtD)/3;  LineCEGMaxDif=abs(LineCEGAveBelow-LineCEGAveAbove);  LineDEFAveBelow=(PtG+PtH+PtI)/3;  LineDEFAveAbove=(PtA+PtB+PtC)/3;  LineDEFMaxDif=abs(LineDEFAveBelow-LineDEFAveAbove);  /*  Find the maximum value of the absolute differences  from the four possibilities,  */  MaxDif=MAX(LineAEIMaxDif,LineBEHMaxDif);  MaxDif=MAX(LineCEGMaxDif,MaxDif);  MaxDif=MAX(LineDEFMaxDif,MaxDif);  /*  If maximum difference is above the threshold,set  the pixel of interest(center pixel)to white,If  below the threshold optionally copy the input image  to the output image,This copying is controlled by  the parameter Overlay,  */  if(MaxDif>=Threshold)   PutPixelInImage(OutputImageBuffer,ImageCol,ImageRow,WHITE);  else if(Overlay)   PutPixelInImage(OutputlmageBuffer,ImageCol,ImageRow,PtE);}}return(NoError);}<!-- SIPO <DP n="39"> --><dp n="d39"/>/****************************************//* FRPOCES.H *//* Image Processing Header File *//* Frame Processing Functions *//*written in Turbo C 2.0 *//****************************************//*User defined image combination type*/typedef enum{And,Or,Xor,Add,Sub,Mult,Div,Min,Max,Ave,Overlay}BitFunction;/*Frame Process Function Prototypes*/void CombinteImages(BYTE huge *SImage,   unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   BYTE huge *DImage,   unsigned DCol,unsigned DRow,   enum BitFunction CombineType,   short Scale);<!-- SIPO <DP n="40"> --><dp n="d40"/>/****************************************//* FPROCES.C *//*Image Processing Code*//*Frame Process Functions *//*written in Turbo C 2.0*//****************************************/#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<dos.h>#include<alloc.h>#include<process.h>#include<graphics.h>#include"misc.h"#include"pcx.h"#include"vga.h"#include"imagesup.h"#include"frprocess.h"/*Single function performs all image combinations*/void CombineImages(BYTE huge *Slmage,   unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   BYTE huge*DImage,   unsigned DCol,unsigned DRow,   enum BitFunction CombineType,   short Scale){register unsigned SImageCol,SImageRow,DestCol;short SData,DData;unsigned SColExtent,SRowExtentif(ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"CombineImages")&amp;&amp;   ParameterCheckOK(DCol,DRow,DCol+SWidth,DRow+SHeight,"CombineImages")){  SColExtent=SCol+SWidth;  SRowExtent=SRow+SHeight;  for(SImageRow=SRow;SlmageRow<SRowExtent;SImageRow++)  {   /*Reset the destination Column count every row*/   DestCol=DCol;   for(SImageCol=SColSImageCol<SColExtent;SlmageCol++)   {  /*Get a byte of the source and dest image data*/  SData=GetPixelFromImage(SImage,SImageCol,SImageRow);  DData=GetPixelFromImage(DImage,DestCol,DRow);  /*Combine source and dest data according to parameter*/  switch(CombineType)  {   case And   DData &amp;=SData;   break;   case Or;   DData |=SData;   break;   case Xor;   DData^=SData;   break;<!-- SIPO <DP n="41"> --><dp n="d41"/>   case Add;   DData+=SData;   break;   case Sub;   DData-=SData;   break;   case Mult;   DData*=SData;   break;   case Div;   if(SData!=0)   DData/=SData;   break;   case Min   DData=MIN(SData,DData);   break;   case Max;   DData=MAX(SData,DData);   break;   case Ave;   DData=(SData+DData)/2;   break;   case Overlay;   DData=SData;   break;  }  /*  Scale the resultant data if requested to. A positive  Scale value shifts the destination data to the right  thereby dividing it by a power of two. A zero Scale  value leaves the data untouched,A negative Scale  value shifts the data left thereby multiplying it by  a power of two  */  if(Scale<0)   DData<<=abs(Scale);   else if(Scata>0)   DData>>=Scale;   /*Don′t let the pixel data get out of range*/   DData=(DData<MINSAMPLEVAL)?MINSAMPLEVAL;DData;   DData=(DData>MAXSAMPLEVAL)?MAXSAMPLEVAL;DData;   PutPixelInImage(DImage,DestCol++,DRow,DData);  }   /*Bump to next row in the destination image*/  DRow++;}}}<!-- SIPO <DP n="42"> --><dp n="d42"/>/****************************************//* GEPROCES.H*//* Image Processing Header File *//* Geometric Processing Functions *//*written in Turbo C 2.0 *//****************************************//*Misc user defined types*/typedef enum{HorizMirror,VertMirror)MirrorType;/*Geometric processes function protorypes*/void ScaleImage(BYTE huge *InImage,unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   double ScaleH,double Scale V,   BYTE huge *OutImage,   unsigned DCol,unsigned DRow,   unsigned Interpolate);void SizeImage(BYTE huge *InImage,unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   BYTE huge*OutImage,   unsigned DCol,unsigned DRow,   unsigned DWidth,unsigned DHeight,   unsigned Interpolate);void RotateImage(BYTE huge *InImage,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,double Angle,   BYTE huge *OutImage,unsigned Interpolate);void TranslateImage(BYTE huge*InImage,   unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   BYTE huge *OutImage,   unsigned DCol,unsigned DRow,   unsigned EraseFlag);void MirrorImage(BYTE huge *InImage,   unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   enum MirrorType WhichMirror,   BYTE huge *OutImage,   unsigned DCol,unsigned DRow);<!-- SIPO <DP n="43"> --><dp n="d43"/>  /****************************************/  /* GEPROCES.C */  /* Image Processing Code*/  /* Geometric Processing Functions */  /* written in Turbo C 2.0 */  /****************************************/  #incIude<stdio.h>  #include<conio.h>  #include<dos.h>  #include<alloc.h>  #include<process.h>  #include<math.h>  #include<graphics.h>  #include"misc.h"  #include"pcx.h"  #include"vga.h"  #include"imagesup.h"  void ScaleImage(BYTE huge *InImage,unsigned SCol,unsigned SRow   unsigned SWidth,unsigned SHeight,   double ScaleH,double Scale V,   BYTE huge *OutImage,   unsigned DCol,unsigned DRow   unsigned Interpolate){  unsigned Dest Width,DestHeight;  unsigned PtA,PtB,PtC,PtD,PixelValue;  register unsigned SPixelColNum,SPixelRowNum,DestCol,DestRow;  double SPixelColAddr,SPixelRowAddr;  double ColDelta,RowDelta;  double ContribFromAandB,ContribFromCandD;  DestWidth=ScaleH *SWidth+0.5;  DestHeight=ScaleV*SHeight+0.5;  if(ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"ScaleImage")&amp;&amp;   ParameterCheckOK(DCol,DRow,DCol+DestWidth,DRow+DestHeight,"Scalelmage"))  {   /*Calculations from destination perspective*/   for(DestRow=0;DestRow<DestHeight;DestRow++)   {  SPixelRowAddr=DestRow/ScaleV;  SPixelRowNum=(unsigned)SPixelRowAddr;  RowDelta=SPixelRowAddr-SPixelRowNum;  SPixelRowNum+=SRow;   for(DestCol=0;DestCol<DestWidth;DestCol++)   {  SPixelColAddr=DestCol/ScaleH;  SPixelColNum=(unsigned)SPixelColAddr;  ColDelta =SPixelColAddr-SPixelColNum;  SPixelColNum+=SCol;  if(Interpolate)  {   /*  SPixelColNum and SPixelRowNum now contain the pixel  coordinates of the upper left pixel of the targetted  pixel′s(point X)neighborhood,This is point A below;   A B  X<!-- SIPO <DP n="44"> --><dp n="d44"/>   C D   We must retrieve the brightness level of each of the   four pixels to calculate the value of the Pixel put into   the destination image,   Get point A brightness as it will always lie within the   input image area,Check to make sure the other points are   within also,If so use their values for the calculations,   If not,set them all equal to point A’s value,This induces   an error but only at the edges on an image   */   PtA=GetPixelFromlmage(InImage,SPixelColNum,SPixelRowNum);   if(((SPixelColNum+1)<MAXCOLS)&amp;&amp;((SPixelRowNum+1)<MAXROWS))   {   PtB=GetPixelFromlmage(InImage,SPixelColNum+1,SPixelRowNum);   PtC=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum+1);   PtD=GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum+1);   }  else   {   /*All points have equal brightness*/   PtB=PtC=PtD=PtA;   }   /*   Interpolate to find brightness contribution of each pixel   in neighborhood,Done in both the horizontal and vertical   directions,   */   ContribFromAandB=ColDelta*((double)PtB-PtA)+PtA;   ContribFromCandD=ColDelta*((double)PtD-PtC)+PtC;   PixelValue=0.5+ContribFromAandB+   (ContribFromCandD-ConribFromAandB)*RowDelta;   }   else   PixelValue=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum)   /*Put the pixel into the destination buffer*/   PutPixelInImage(OutImage,DestCol+DCol,DestRow+DRow,PixelValue);   }}}}void SizeImage(BYTE huge *InImage,unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   BYTE huge *OutImage,   unsigned DCol,unsigned DRow,   unsigned DWidth,unsigned DHeight,   unsigned Interpolate){double HScale,VScale;/*Check for parameters out of range*/if(ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"SizeImage")&amp;&amp;   ParameterCheckOK(DCol,DRow,DCol+DWidth,DRow+DHeight,"SizeImage")){/*Calculate horizontal and vertical scale factors requiredto fit specified portion of input image into specified portionof output image.*/<!-- SIPO <DP n="45"> --><dp n="d45"/>   HScale=(double)DWidth/(double)SWidth;   VScale=(double)DHeight/(double)SHeight;   /*Call ScaleImage to do the actual work*/   ScaleImage(InImage,SCol,SRow,SWidth,SHeight,HScale,VScale,   OutImage,DCol,DRow,Interpolate)   }}void RotateImage(BYTE huge *InImage,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,double Angle,   BYTE huge *OutImage,unsigned Interpolate){  register unsigned ImageCol,ImageRow  unsigned CenterCol,CenterRow,SPixelColNum,SPixelRowNum  unsigned ColExtent,RowExtent,PixelValue;  unsigned PtA,PtB,PtC,PtD;  double DPixelRelativeColNum,DPixelRelativeRowNum;  double CosAngle,SinAngle,SPixelColAddr,SPixelRowAddr;  double ColDelta,RowDelta;  double ContribFromAandB,ContribFromCandD;  if(ParameterCheckOK(Col,Row,Col+Width,Row+Height,"RotateImage"))  {   /*Angle must be in 0..359.9*/   while(Angle>=360.0)  Angle-=360.0;   /*Convert angle from degrees to radians*/   Angle*=((double)3.14159/(double)180.0);   /*Calculate angle values for rotation*/   CosAngle=cos(Angle);   SinAngle=sin(Angle);   /*Center of rotation*/   CenterCol=Col+Width/2;   CenterRow=Row+Height/2;   ColExtent=Col+Width;   RowExtent=Row+Height;   /*   All calculations are performed from the destination image   perspective,Absolute pixel values must be converted into   inches of display distance to keep the aspect value   correct when image is rotated,After rotation,the calculated   display distance is converted back to real pixel values.   */   for(ImageRow=RowImageRow<RowExtentImageRow++)   {   DPixelRelativeRowNum=(double)ImageRow-CenterRow;   /*Convert row value to display distance from image center*/   DPixelRelativeRowNum*=LRINCHESPERPIXEL VERT;   for(ImageCol=ColImageCol<ColExtentImageCol++)   {   DPixelRelativeColNum=(double)ImageCol-CenterCol;   /*Convert col value to display distance from image center*/   DPixelRelativeColNum*=LRINCHESPERPIXELHORIZ;   /*   Calculate source pixel address from destination<!-- SIPO <DP n="46"> --><dp n="d46"/>pixels position.*/SPixelColAddr=DPixelRelativeColNum*CosAngle-   DPixelRelativeRowNum*SinAngle;SPixelRowAddr=DPixelRelativeColNum*SinAngle+   DPixelRelativeRowNum*CosAngle;/*Convert from coordinates relative to imagecenter back into absolute coordinates.*//*Convert display distance to pixel location*/SPixelColAddr*=LRPIXELSPERINCHHORIZ;SPixelColAddr+= CenterCol;SPixelRowAddr*=LRPIXELSPERINCHYERT;SPixelRowAddr+=CenterRow;SPixelColNum=(unsigned)SPixelColAddr;SPixelRowNum=(unsigned)SPixelRowAddr;ColDelta=SPixelColAddr-SPixelColNum;RowDelta=SPixelRowAddr-SPixelRowNum;if(Interpolate){/*SPixelColNum and SPixelRowNum now contain the pixelcoordinates of the upper left pixel of the targettedpixel′s(point X)neighborhood,This is point A below;   A B   X   C DWe must retrieve the brightness level of each of thefour pixels to calculate the value of the ptxel put intothe destination image.Get point A brightness as it will always lie within theinput image area.Check to make sure the other points arewithin also.If so use their values for the calculations.If not.set them all equal to point A’s value,This inducesan error but only at the edges on an image.*/PtA=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum);if(((SPixelColNum+1)<MAXCOLS)&amp;&amp;((SPixelRowNum+1)<MAXROWS)){   PtB=GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum);  PtC=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum+1);  PtD=GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum+l);}else{   /*All points have equal brightness*/   PtB=PtC=PtD=PtA;}/*Interpolate to find brightness contribution of each pixelin neighborhood,Done in both the horizontal and verticaldirections.*/ContribFromAandB=ColDelta*((double)PtB-PtA)+PtA;ContribFromCandD=ColDelta*((double)PtD-PtC)+PtC;PixelValue=0.5+ContribFromAandB+   (ContribFromCandD-ContribFromnAandB)*RowDelta;<!-- SIPO <DP n="47"> --><dp n="d47"/>   }   else   PixelValue=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum);   /*Put the pixel into the destination buffer*/   PutPixelInImage(OuImage,ImageCol,ImageRow,PixelValue);   }  }}}/*Caution;images must not overlap*/void TranslateImage(BYTE huge *InImage,  unsigned SCol,unsigned SRow,  unsigned SWidth,unsigned SHeight,  BYTE huge *OutImage,  unsigned DCol,unsigned DRow,  unsigned EraseFlag){register unsigned SImageCol,SImageRow,DestCol;unsigned SColExtent,SRowExtent;/*Check for parameters out of range*/if(ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"TranslateImage")&amp;&amp;   ParameterCheckOK(DCol,DRow,DCol+SWidth,DRow+SHeight,"TranslateImage")){   SColExtent=SCol+SWidth;   SRowExtent=SRow+SHeight;   for(SImageRow=SRow;SImageRow<SRowExtent;SImageRow++)   {   /*Reset the destination Column count every row*/   DestCol=DCol;   for(SImageCol=SCol;SImageCol<SColExtent;SlmageCol++)   {  /*Transter byte of the image data between buffers*/  PutPixelInImage(OutImage,DestCol++,DRow,   GetPixelFromImage(InImage,SImageCol,SImageRow));   }   /*Bump to next row in the destination image*/   DRow++;  }  /*If erasure specified,blot out original image*/  if(EraseFlag)   ClearImageArea(InImage,SCol,SRow,SWidth,SHeight,BLACK);}}void MirrorImage(BYTE huge *InImage,   unsigned SCol,unsigned SRow,   unsigned SWidth,unsigned SHeight,   enum Mirror Type WhichMirror,   BYTE huge *OutImage,   unsigned DCol,unsigned DRow){register unsigned SImageCol,SImageRow,DestCol;unsigned SColExtent,SRowExtent;/*Check for parameters out of range*/if(ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"MirrorImage")&amp;&amp;<!-- SIPO <DP n="48"> --><dp n="d48"/>   ParameterCheckOK(DCol,DRow,DCol+SWidth,DRow+SHeight,"MirrorImage")){  SColExtent=SCol+SWidth;  SRowExtent=SRow+SHeight;  switch(WhichMirror)  {  case HorizMirror;   for(SImageRow=SRow;SImageRow<SRowExtent;SImageRow++)   {   /*Reset the destination Column count every row*/   DestCol=DCol+SWidth;   for(SImageCol=SCol;SImageCol<SColExtent;SImageCol++)   {   /*Transfer byte of the image data between buffers*/   PutPixelInImage(OutImage,--DestCol,DRow,  GetPixelFromImage(InImage,SImageCol,SImageRow));   }   /*Bump to next row in the destination image*/   DRow++   }   break;case VertMirror;   DRow+=(SHeighr-1);   for(SImageRow=SRow;SImageRow<SRowExtent;SImageRow++)   {   /*Reset the destinauon Column count every row*/   DestCol=DCol;   for(SImageCol=SCol;SImageCol<SColExtent;SImageCol++)   {   /*Transfer byte of the image data between buffers*/   PutPixelInImage(OutImage,DestCol++,DRow,   GetPixelFromImage(InImage,SImageCol,SImageRow));   }   /*Bump to next row in the destination image*/   DRow--;  }  break;}}}<!-- SIPO <DP n="49"> --><dp n="d49"/>/******************************************//*IMAGESUP.H *//*Image Processing Header File *//* Image Processing Support Functions *//* written in Turbo C 2.0 *//***************************************//*This file includes the general equates used for all of theimage processing code in part two of this book,Throughoutthese equates,a 320x200 256 color image is assumed,If theresolution of the processed pictures change,the equatesMAXCOLS and MAXROWS must change accordingly.*//*Pixel Sample Information and Equates*/#define MAXSAMPLEBITS 6 /*6 bits from digitizer*/#define MINSAMPLEVAL 0 /*Min sample value=0*//*Max num of sample values*/#define MAXQUANTLEVELS(1<<MAXSAMPLEBITS)/*Max sample value=63*/#define MAXSAMPLEVAL (MAXQUANTLEVELS-1)/*Image Resolution Equates*/#define MINCOLNUM0 /*Column 0*/#define MAXCOLS LRMAXCOLS/*320 total columns*/#define MAXCOLNUM(MAXCOLS-l)/*Last column is 319*/#define MINROWNUM0 /*Row 0*/#define MAXROWS LRMAXROWS /*200 total rows*/#define MAXROWNUM (MAXROWS-1)/*Last row is 199*/#define RASTERSIZE((long)MAXCOLS*MAXROWS)#define MAXNUMGRAYCOLORS MAXQUANTLEVELS/*histogram equates*/#define HISTOCOL0#define HISTOROW0#define HISTOWIDTH 134#define HISTOHEIGHT 84#define BLACK 0#define WHITE 63#define AXISCOL(HISTOCOL+3)#define AXISROW(HISTOROW+HISTOHEIGHT-5)#define AXISLENGTH MAXQUANTLEVELS*2-1#define DATACOL AXISCOL#define DATAROW AXISROW-1#define MAXDEFLECTION (HISTOHEIGHT-10)/*External Function Declarations and Prototypes*/void CopyImage(BYTE huge *SourceBuf,BYTE huge *DestBuf);BYTE GetPixelFromImage(BYTE huge *Image,unsigned Col,unsigned Row);CompletionCode PutPixelInImage(BYTE huge *Image,unsigned Col,   unsigned Row,unsigned Color);CompletionCode DrawHLine(BYTE huge *Image,unsigned Col,unsigned Row,   unsigned Length,unsigned Color);<!-- SIPO <DP n="50"> --><dp n="d50"/>CompletionCode DrawVLine(BYTE huge *Image,unsigned Col,unsigned Row   unsigned Length,unsigned Color);void ReadImageAreaToBuf(BYTE huge *Image,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,   BYTE huge *Buffer);void WriteImageAreaFromBuf(BYTE huge *Buffer,unsigned BufWidth,   unsigned BufHeight,BYTE huge *Image.   unsigned ImageCol,unsigned ImageRow);void ClearImageArea(BYTE huge *Imnage,unsigned Col,unsigned Row,  unsigned Width,unsigned Height,  unsigned PixelValue);CompletionCode parameterCheckOK(unsigned Col,unsigned Row  unsigned ColExtent,unsigned RowExtent,  char*ErrorStr);<!-- SIPO <DP n="51"> --><dp n="d51"/>/****************************************//* IMAGESUP.C *//*Image Processing Support Functions *//*written in Turbo C 2.0 *//****************************************/#include<stdio.h>#include<process.h>#include<conio.h>#include<dos.h>#include<alloc.h>#include<mem.h>#include<graphics.h>#include"misc.h"#include"pcx.h"#include"vga.h"#include"imagesup.h"extern srtuct PCX_File PCX Data;extern unsigned Image Width;extern unsigned ImageHeight;/*Image Processing Support Functions-See text for details.*//*Copy a complete image from source buffer to destination buffer*/void Copylmage(BYTE huge *SourceBuf,BYTE huge *DestBuf){movedata(FP_SEG(SourceBuf),F(xiàn)P OFF(SourceBuf).   FP_SEG(DestBuf),F(xiàn)P OFF(DestBuf).   (unsigned)RASTERSIZE);}/*NOTE;to index into the image memory like an array,the indexvalue must be a long variable type,NOT just cast to long*/BYTE GetPixelFromImage(BYTE huge *Image,unsigned Col,unsigned Row){unsigned long PixelBufOffset;if((Col<Image Width)&amp;&amp;(Row<ImageHeight)){PixelBufOffset=Row; /*done to prevent overflow*/PixelBufOffset*=ImageWidth;PixelBufOffset+=Col;return(Image[PixelBufOffset]);}printf("GetPixelFromImage Error;Coordinate out of range\n");printf(*Col =%d Row=%d\n",Col,Row);return(FALSE);}CompletionCode PutPixelInImage(BYTE huge *Image,unsigned Col,   unsigned Row,unsigned Color){<!-- SIPO <DP n="52"> --><dp n="d52"/>unsigned long PixelBufOffset;if((Col<Image Width)&amp;&amp;(Row<ImageHeight)){  PixelBufOffset=Row; /*done to prevent overflow*/  PixelBufOffset*=ImageWidth;  PixelBufOffset+=Col;  Image[PixelBufOffset]=Color;  return(TRUE);}else{  printf("PutPixelInImage Error;Coordinate out of range\n");  printf("Col=%d Row=%d\n",Col,Row);  return(FALSE);}}/*NOTE;A length of O is one pixel on A length of I is two pixelson,That is why length is incremented before being used*/CompletionCode DrawHLine(BYTE huge *Image,unsigned Col,unsigned Row   unsigned Length,unsigned Color){  if((Col<Image Width)&amp;&amp;((Col+Length)<=Image Width)&amp;&amp;   (Row<ImageHeight)){  Length++;  while(Length--)   PutPixelInImage(Image,Col++,Row,Color);  return(TRUE);}else{  printf("DrawHLine Error;Coordinate out of range\n");  printf("Col =%d Row=%d Length=%d\n",Col,Row,Length);  return(FALSE);}}CompletionCode DrawVLine(BYTE huge *Image,unsigned Col,unsigned Row,   unsigned Length,unsigned Color){if((Row<ImageHeight)&amp;&amp;((Row+Length)<=ImageHeight)&amp;&amp;   (Col<ImageWidth)){   Length++;   while(Length--)   PutPixelInImage(Image,Col,Row++,Color);   return(TRUE);}else{  printf("DrawVLine Error;Coordinate out of range\n");  printf("Col=%d Row=%d Length=%d\n",Col,Row,Length);  return(FALSE);}}void ReadImageAreaToBuf(BYTE huge *Image,unsigned Col,unsigned Row,<!-- SIPO <DP n="53"> --><dp n="d53"/>   unsigned Width,unsigned Height,BYTE huge *Buffer)  {   unsigned long PixelBufOffset=OL;   register unsigned ImageCol,ImageRow;   for(ImageRow=Row;ImageRow<Row+Height;ImageRow++)  for(ImageCol=Col;ImageCol<Col+Width;ImageCol++)   Buffer[PixelBufOffset++]=   GetPixelFromlmage(Image,ImageCol,ImageRow);  }  void WriteImageAreaFromBuf(BYTE huge *Buffer,unsigned BufWidth,   unsigned BufHeight,BYTE huge *Image,   unsigned ImageCol,unsigned ImageRow)  {   unsigned long PixelBufOffset;   register unsigned BufCol,BufRow,CurrentImageCol,   for(BufRow=O;BufRow<BufHeight;BufRow++)   {   CurrentImageCol=ImageCol;   for(BufCol=O;BufCol<BufWidth;BufCol++)  {   PixelBufOffset=(unsigned long)BufRow*BufWidth+BufCol;   PutPixelInImage(Image,CurrentImageCol,ImageRow,Buffer[PtxelBufOffset]);   CurrentImageCol++;  }  ImageRow++;   }  }  void ClearImageArea(BYTE huge *Image,unsigned Col,unsigned Row,  unsigned Width,unsigned Height,  unsigned PixelValue)  {   register unsigned BufCol,BufRow;   for(BufRow=O;BufRow<Height;BufRow++)  for(BufCol=O;BufCol<Width;BufCol++)   PutPixelInImage(Image,BufCol+Col,BufRow+Row,PtxelValue);  }  /*  This function checks to make sure the parameters passed to  the image processing functions are all within range,If so  a TRUE is returned,If not,an error message is output and  the calling program is terminated.  */  CompletionCode ParameterCheckOK(unsigned Col,unsigned Row,  unsigned ColExtent,unsigned RowExtent,  char*FunctionName)  {   if((Col>MAXCOLNUM)‖(Row>MAXROWNLUM)‖  (ColExtent>MAXCOLS)‖(RowExtent>MAXROWS))  {   restorecrtmode();   printf(*Parameter(s)out of range in function;%s\n".FunctionName);   printf("Col =%d Row=%d ColExtent=%d RowExtent=%d\n",   Col,Row,ColExtent,RowExtent);<!-- SIPO <DP n="54"> --><dp n="d54"/>  exit(EBadParms).}return(TRUE);}<!-- SIPO <DP n="55"> --><dp n="d55"/>/****************************************//*PTPROCES.H *//* Image Processing Header File *//* Point Processing Functions *//*written in Turbo C 2.0 *//****************************************/extern unsigned Histogram[MAXQUANTLEVELS);/* Function Prototypes for support and histogram functions*/void InitializeLUT(BYTE *LookUpTable);void PtTransform(BYTE huge *ImageData,unsigned Col,   unsigned Row,unsigned Width,   unsigned Height,BYTE *LookUpTable);void GenHistogram(BYTE huge *ImageData,unsigned Col,   unsigned Row,unsigned Width,   unsigned Height);void DisplayHist(BYTE huge *ImageData,unsigned Col,   unsigned Row,unsigned Width,   unsigned Height);/*Point transform functions*/void AdjImageBrightness(BYTIE huge *ImageData,short BrightnessFactor   unsigned Col,unsigned Row,   unsigned Width,unsigned Height);void NegateImage(BYTE huge *ImageData,unsigned Threshold,   unsigned Col,unsigned Row,   unsigned Width,unsigned Height);void ThresholdImage(BYTE huge *ImageData,unsigned Threshold,  unsigned Col,unsigned Row,  unsigned Width,unsigned Height);void StretchImageContrast(BYTE huge *ImageData,unsigned *HistoData  unsigned Threshold,  unsigned Col,unsigned Row,  unsigned Width,unsigned Height);<!-- SIPO <DP n="56"> --><dp n="d56"/>/****************************************//*PTPROCES.C *//*Image Processing Code*//* Point Process Functions *//*written in Turbo C 2.0 *//********************************…*****/#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<dos.h>#include<alloc.h>#include<process.h>#include<graphics.h>#include"misc.h"#include"pcx.h"#include"vga.h"#include"imagesup.h"/*Histogram storage location*/unsigned Histogram[MAXQUANTLEVELS];/*Look Up Table(LUT)FunctionsInitialize the Look Up Table(LUT)for straight throughmapping,If a point transform is performed on an initializedLUT,output data will equal input data,This function isusually called in preparauon for modification to a LUT.*/void InitializeLUT(BYTE *LookUpTable){register unsigned Indexfor(Index=O;Index<MAXQUANTLEVELS;Index++)LookUpTable[Index]=Index;}/*This function performs a point transform on the portion of theimage specified by Col,Row,Width and Height,The actualtransform is contained in the Look Up Table who addressis passed as a parameter.*/void PtTransform(BYTE huge *ImageData,unsigned Col,unsigned Row,   unsigned Width,unsigned Height,BYTE *LookUpTable){register unsigned ImageCol,ImageRow;regiser unsigned ColExtent,RowExtent;ColExtent=Col+Width;<!-- SIPO <DP n="57"> --><dp n="d57"/>RowExtent=Row+Height;if(ParameterCheckOK(Col,Row,ColExtent,RowExtent,"PtTransform"))for(ImageRow=RowImageRow<RowExtent;ImageRow++)  for(ImageCol=Col;ImageCol<ColExtent;ImageCol++)   PutPixelInImage(ImageData,ImageCol,ImageRow,   LookUpTable[GetPixelFromImage(ImageData,ImageCol,ImageRow)]);}/*start of histogram functionsThis function calculates the histogram of any portion of an image*/void GenHistogram(BYTE huge *ImageData,unsigned Col,unsigned Row,   unsigned Width,unsigned Height){register unsigned ImageRow,ImageCol,RowExtent,ColExtent;register unsigned Index;/*clear the histogram array*/for(Index=O;Index<MAXQUANTLEVELS;Index++)  Histogram[Index]=O;RowExtent=Row+Height;ColExtent=Col+Width;if(ParameterCheckOK(Col,Row,ColExtent,RowExtent"GenHistogram")){/*calculate the histogram*/for(ImageRow=Row;ImageRow<RowExtent;ImageRow++)   for(ImageCol=Col;ImageCol<ColExtentImageCol++)   Histogram[GetPixelFromImage(ImageData,ImageCol,ImageRow)]+=1}}/*This function calculates and displays the histogram of an imageor partial image,When called it assumes the VGA is alreadyin mode 13 hex.*/void DisplayHist(BYTE huge *ImageData,unsigned Col,unsigned Row,   unsigned Width,unsigned Heighi){BYTE huge *Buffer;register unsigned Index,LineLength,XPos,YPos;unsigned MaxRepeat;/*Alloeate enough memory to save image under histogram*/Buffer =(BYTE huge *)farcalloc((long)HISTOWIDTH*HISTOHEIGHT,sizeof(BYTE));if(Buffer==NULL){  printf("No buffer memory\n");  exit(ENoMemory);}/*Save a copy of the image*/ReadImageAreaToBuf(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH,HISTOHEIGHT,   Buffer);<!-- SIPO <DP n="58"> --><dp n="d58"/>/*Set VGA color register 65 to red,66 to green and 67 toblue so the histogram can be visually separated fromthe continuous tone image,*/SetAColorReg(65,63,0,0);SetAColorReg(66,0,63,0);SetAColorReg(67,0,0,63);/*Calculate the histogram for the image*/GenHistogram(ImageData,Col,Row,Width,Height);MaxRepeat=0;/*Find the pixel value repeated the most It will be used forscaling,*/for(Index=0Index<MAXQUANTLEVELS;Index++)MaxRepeat=(Histogram[Index]>MaxRepeat)?Histogram[Index];MaxRepeat;/*Fill background area of histogram graph*/ClearImageArea(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH,HISTOHEIGHT,67);/*Draw THe bounding box for the histogram*/DrawVLine(ImageData,HISTOCOL,HISTOROW,HISTOHEIGHT-1,BLACK);DrawVLine(ImageData,HISTOCOL+HISTOWIDTH-1,HISTOROW,HISTOHEIGHT-1,BLACK);DrawHLine(ImaeeData,HISTOCOL,HISTOROW+HISTOHEIGHT-1,HISTOWIDTH-1,BLACK)DrawHLine(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH-1,BLACK);/*Data base line*/DrawHLine(ImageData,AXISCOL,AXISROW,AXISLENGTH,WHITE);DrawHLine(ImageData,AXISCOL,AXISROW+1,AXISLENGTH,WHITE)/*Now do the actual histogram rendering into theimage buffer.*/for(Index=0Index<MAXQUANTLEVELSIndex++){LineLength=(unsigned)(((long)Histogram[Index] *MAXDEFLECTION)/   (long)MaxRepeat);XPos=DATACOL+Index*2;YPos=DATAROW-LineLength;DrawVLine(ImageData,XPos,YPos,LineLength,66);}/*Display the image overlayed with the histogram*/DisplayImageInBuf(ImageData,NOVGAINIT,WAITFORKEY);/*After display,restore image data under histogram*/WriteImageAreaFromBuf(Buffer,HISTOWIDTH,HISTOHEIGHT,ImageData,   HISTOCOL,HISTOROW);farfree((BYTE far*)Buffer);}<!-- SIPO <DP n="59"> --><dp n="d59"/>/*Various Point Transformation Functions*/void AdjImageBrightness(BYTE huge *ImageData,short BrightnessFactor,   unsigned Col,unsigned Row,   unsigned Width,unsigned Height){register unsigned Index;register short NewLevel;BYTE LookUpTable[MAXQUANTLEVELS];for (Index=MINSAMPLEVAL;Index<MAXQUANTLEVELS;Index++){  NewLevel=Index+BrightnessFactor;  NewLevel=(NewLevel<MINSAMPLEVAL)?MINSAMPLEVAL;NewLevel;  NewLevel=(NewLevel>MAXSAMPLEVAL)?MAXSAMPLEVAL;NewLevel  LookUpTable[Index]=NewLevel;}PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);}/*This function will negate an image pixel by pixel,Threshold isthe value of image data where the negatation begins,Ifthreshold is 0,all pixel values are negated,That is,pixel value 0becomes 63 and pixel value 63 becomes 0.Ifthreshold is greaterthan 0.the pixel values in the range 0..Threshold-1 are leftalone while pixel values between Threshold..63 are negated*/void NegateImage(BYTE huge *ImageData,unsigned Threshold,   unsined Col,unsigned Row,   unsigned Width,unsigned Height){register unsigned Index;BYTE LookUpTable[MAXQUANTLEVELS];/* Straight through mapping initially*/InitializeLUT(LookUpTable);/*from Threshold onward,negate entry in LUT*/for(index=Threshold;Index<MAXQUANTLEVELS;Index++)  LookUpTable[Index]=MAXSAMPLEVAL-Index;PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);}/*This function converts a gray scale image,to a binary image with eachpixel either on(WHITE)or off(BLACK),The pixel level atwhich the cut off is made is controlled by Threshold,Pixelsin the range 0..Threshold-1 become black while pixel valuesbetween Threshold..63 become white.*/<!-- SIPO <DP n="60"> --><dp n="d60"/>void ThresholdImage(BYTE huge *ImageData,unsigned Threshold   unsigned Col,unsigned Row.   unsigned Width,unsigned Height){register unsigned Index;BYTE LookUpTable[MAXQUANTLEVELS];for(Index=MINSAMPLEVAL;Index<Threshold;Index++)  LookUpTable[Index]=BLACK;for(Index=Threshold;Index<MAXQUANTLEVELS;Index++)   LookUpTable[Index]=WHITE;PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);}void StretchImageContrast(BYTE huge *ImageData,unsigned *HistoData,  unsigned Threshold,   unsigned Col,unsigned Row,   unsigned Width,unsigned Height){register unsigned Index,NewMin,NewMax;double StepSiz,StepValBYTE LookUpTable[MAXQUANTLEVELS];/*Search from the low bin towards the high bin for the first one thatexceeds the threshold*/for(Index=0;Index<MAXQUANTLEVELS;Index++)if(HistoData[Index]>Threshold)  break;NewMin=Index;/*Search from the high bin towards the low bin for the first one thatexceeds the threshold*/for(Index=MAXSAMPLEVAL;Index>NewMin;Index--)if(HistoData[Index]>Threshold)  break;NewMax=Index;StepSiz=(double)MAXQUANTLEVELS/(double)(NewMax-NewMin+1);StepVal=0,0;/*values below new minimum are assigned zero in the LUT*/for(Index=0;Index<NewMin;Index++)LookUpTable[Index]=MINSAMPLEVAL;/*values above new maximum are assigned the max sample value*/for(Index=NewMax+1;Index<MAXQUANTLEVELS;Index++)  LookUpTable[Index]=MAXSAMPLEVAL;/*values between the new minimum and new maximum are stretched*/for(Index=NewMin;Index<=NewMax;Index++){<!-- SIPO <DP n="61"> --><dp n="d61"/>LookUpTable[Index]=StepVal;StepVal+=StepSiz;}/*Look Up Table is now prepared to point transform the image data*/PtTransform(ImageData,Col,Row,width,Height,LookUpTable);}
權(quán)利要求
1.一種二維顯示裝置,其上所成圖像由分立像素提供,此顯示裝置具有在整個圖像上逐個像素地動態(tài)地改變到位于此顯示裝置前面的觀察者的明視視覺距離的裝置,每一單個像素呈現(xiàn)于其上,從而產(chǎn)生一個三維圖像。
2.如權(quán)利要求1所述的顯示裝置,其中用于動態(tài)變化的裝置包括,一個透明光學(xué)折射元件陣列,分別在像素前對準(zhǔn)且每個都有一個沿與圖像大致平行取向的折射表面逐漸改變的焦距;和在一個像素范圍內(nèi)根據(jù)所需深度而精細(xì)位移出射光位置的裝置,以使在此光學(xué)元件的輸入折射表面上有一個光束輸入位置的相應(yīng)位移,從而根據(jù)光輸入位置改變至觀察者的明視視覺距離。
3.如權(quán)利要求2所述的顯示裝置,其中所述折射表面的形狀形成為可提供變化的焦距。
4.如權(quán)利要求2所述的顯示裝置,其中所述光學(xué)折射元件由梯度折射率的光學(xué)材料制成,其折射率沿折射元件逐漸變化以產(chǎn)生變化的焦距。
5.如權(quán)利要求2所述的顯示裝置,其中所述位移與所述焦距的關(guān)系是線性的。
6.如權(quán)利要求2所述的顯示裝置,其中所述位移與所述焦距的關(guān)系是非線性的。
7.如權(quán)利要求2所述的顯示裝置,其中每一光學(xué)折射元件具有一個相對此光學(xué)折射元件光軸徑向變化的焦距,且所述位移裝置在一個像素內(nèi)徑向地位移光出射的位置。
8.如權(quán)利要求2所述的顯示裝置,其中每一光學(xué)折射元件是狹長的且具有從一端沿其長度方向改變的焦距,且此顯示裝置在一像素內(nèi)線性位移光出射點。
9.如權(quán)利要求2,7或8所述的顯示裝置,其中顯示裝置包括液晶顯示裝置,場致發(fā)光裝置及等離子體顯示裝置之一種作為光源。
10.如權(quán)利要求8所述的顯示裝置,其中此顯示裝置包括一個陰極射線管,此陰極射線管上具有大量狹長的熒光像素并含有用于沿每一熒光像素位移電子束的裝置,從而對發(fā)光點及光在對應(yīng)光學(xué)元件的入射點做相似的位移。
11.如權(quán)利要求10所述的顯示裝置,其中電子束橫截面為矩形。
12.如權(quán)利要求10所述的顯示裝置,其中電子束橫截面為橢圓。
13.如權(quán)利要求10所述的顯示裝置,其中此顯示裝置為電視接收機,具有從接收信號中提取每一像素深度成分的裝置和將此深度成分逐個像素地加入傳統(tǒng)水平掃描線以控制水平掃描線垂直高度,從而獲得一階梯狀光柵掃描線的裝置。
14.如權(quán)利要求2所述的顯示裝置,其中在單個光學(xué)元件之間設(shè)置有微小間隙。
15.如權(quán)利要求14所述的顯示裝置,其中在所述間隙中填充有黑色不透光材料。
16.如權(quán)利要求2所述的顯示裝置,其中所述透明光學(xué)元件被制作成塑料材料的模壓片。
17.如權(quán)利要求2所述的顯示裝置,其中所述透明元件設(shè)置在一層注模塑料材料上。
18.如權(quán)利要求2所述的顯示裝置,其中每個光學(xué)元件為含有至少兩個單個光學(xué)構(gòu)件的復(fù)合器件。
19.如權(quán)利要求18所述的顯示裝置,其中所述至少兩個單個光學(xué)構(gòu)件被制作成粘接在一起的至少兩個塑料材料模壓片。
20.如權(quán)利要求18所述的顯示裝置,其中所述至少兩個單個光學(xué)構(gòu)件被制作成在其邊緣可靠連接的至少兩個塑料材料模壓片。
21.如權(quán)利要求8所述的顯示裝置,其中所述顯示裝置為用于攝影透明膠片的顯示裝置或投影機,所述用于位移光出射點的裝置包括一個遮光罩,它被施加于透明片的每個像素以提供一個預(yù)定透射點。
22.如權(quán)利要求1所述的顯示裝置,其中所述二維圖像為印刷或照相圖像,所述用于動態(tài)改變的裝置包括一系列微透鏡,分別與像素對準(zhǔn)且施加于二維圖像上,每一微透鏡具有一相應(yīng)焦距,選擇此焦距以在距觀察者既定距離處顯示相關(guān)像素。
23.一種由二維圖像顯示裝置形成三維圖像的方法,包括,將此二維圖像分解成像素,逐個像素地動態(tài)改變圖像至一個位于其上呈現(xiàn)每一分立像素的所述顯示裝置前面的觀察者的明視視覺距離。
24.如權(quán)利要求23所述的方法,其中所述二維圖像形成在如下裝置之一中,即陰極射線管,液晶顯示裝置,場致發(fā)光裝置,等離子體顯示裝置,照像幻燈片和電影,包括如下步驟,在每一像素內(nèi)位移從二維圖像出射光的位置,并使此出射光通過分別對準(zhǔn)在像素前面的光學(xué)元件,由此出射光進(jìn)入光學(xué)元件的位置決定像素的明視深度。
25.如權(quán)利要求24所述的方法,其中所述位移由二維圖像出射光位置的步驟,包括線性位移由二維圖像出射的光的出射位置。
26.如權(quán)利要求24所述的方法,其中所述位移由二維圖像出射光位置的步驟,包括徑向位移由二維圖像出射的光的出射位置。
27.一種編碼電視廣播信號的方法,包括如下步驟,對每一像素產(chǎn)生一深度信號,并加入此深度信號作為所述廣播信號的成分。
28.一種對按照權(quán)利要求27編碼的電視廣播信號進(jìn)行解碼的方法,包括提取所述深度信號成分的步驟。
29.如權(quán)利要求27所述的編碼電視廣播信號的方法,其中所述產(chǎn)生深度信號的步驟中采用兩個分離攝影鏡頭的三角測量技術(shù)。
30.如權(quán)利要求27所述的編碼電視廣播信號的方法,其中所述產(chǎn)生深度信號的步驟中采用了非光學(xué)深度傳感器。
31.一種對傳統(tǒng)二維成像增進(jìn)三維信息的方法,包括如下步驟,數(shù)字化每一場景,確定場景中的單個物體,給場景中每一個物體設(shè)定一特定深度,掃描場景中的每一像素,根據(jù)特定深度為這些像素設(shè)定相應(yīng)的深度成分。
32.一種二維顯示裝置,包括一個陰極射線管,其上具有大量的矩形熒光像素,每一像素具有一個長度和一個寬度,此陰極射線管還包括用于根據(jù)所需深度沿每一熒光像素長度位移電子束的裝置;和一系列矩形透明光學(xué)折射元件,分別對準(zhǔn)像素的前面且各具有一個長度和一個寬度,每一光學(xué)元件焦距沿其長度方向逐漸變化從而根據(jù)所需要的深度改變距位于其上呈現(xiàn)每一單個像素的所述顯示裝置前的觀察者的明視視覺距離,從而產(chǎn)生一個三維圖像。
33.如權(quán)利要求32所述的顯示裝置,其中所述像素按行對準(zhǔn)。
34.如權(quán)利要求33所述的顯示裝置,其中此顯示裝置為電視接收機,具有從接收信號為每一像素提取深度成分的裝置和將此深度成分加入傳統(tǒng)水平掃描線以逐個像素地控制水平掃描線的垂直高度的裝置,從而可獲得一階梯形光柵掃描線。
35.如權(quán)利要求1所述的顯示裝置,其中用于動態(tài)改變的裝置包括,一系列透明光學(xué)元件,分別對準(zhǔn)在像素前且每個的焦距沿與圖像大致平行定向的表面逐漸改變;和根據(jù)所需深度在像素內(nèi)精細(xì)位移光出射位置的裝置,以使光輸入位置沿光學(xué)元件的輸入表面有一相應(yīng)位移,從而使至觀察者的明視視覺距離根據(jù)光入射位置的位移而改變。
36.如權(quán)利要求1所述的顯示裝置,其中用于動態(tài)改變的裝置包括,一系列透明光學(xué)反射元件,分別對準(zhǔn)在像素前且每個的焦距沿與圖像大致平行定向的反射表面逐漸改變;和根據(jù)所需深度在像素內(nèi)精細(xì)位移光出射位置的裝置,以使光輸入位置沿光學(xué)元件的輸入反射表面有一相應(yīng)位移,從而使至觀察者的明視視覺距離根據(jù)光入射位置的位移而改變。
37.如權(quán)利要求36所述的顯示裝置,其中每一光學(xué)元件包括一個平面鏡和一個凹面鏡。
38.如權(quán)利要求37所述的顯示裝置,其中每一平面鏡制作成一個組合元件的一個表面,此組合元件的另一表面制成一個用于相鄰像素的凹面鏡。
39.如權(quán)利要求10,32或33所述的顯示裝置,其中所述顯示裝置為一個計算機顯示器和基于計算機的視頻驅(qū)動電子設(shè)備,此電子設(shè)備具有由接收自計算機的數(shù)據(jù)從每一像素提取深度成分的裝置,以及逐個像素地將此深度成分加入傳統(tǒng)水平掃描線的裝置,從而獲得一階梯形掃描柵線。
全文摘要
通過逐個像素地改變圖像到觀察者的表觀距離,從二維顯示上獲得三維圖像。這是通過設(shè)置與圖像像素對準(zhǔn)的像素級光學(xué)單元陣列來實現(xiàn)的。在優(yōu)選形式下,每個光學(xué)單元普遍是狹長的且具有沿長度方向變化的焦距,其結(jié)果為光束入射在光學(xué)單元上沿長度的點決定了有關(guān)像素到觀察者的明視視覺距離。在應(yīng)用于陰極射線管的情況下,對入射光位置的控制通過控制電子束在水平掃描時垂直移動一個微小距離來實現(xiàn)。在應(yīng)用于電視時,此垂直距離決定于設(shè)置在電視所接收的廣播信號中的深度信號。對涉及計算機顯示器,電影及靜止印刷圖像的應(yīng)用及實施例也作了描述。
文檔編號H04N13/04GK1175309SQ95197619
公開日1998年3月4日 申請日期1995年12月28日 優(yōu)先權(quán)日1995年1月4日
發(fā)明者紹爾頓·S·茲里特 申請人:視景公司
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1