|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-60DBA025-8FA0-5DF2-90D0-744A016998EE" xml:lang="en"><title>Panoramic |
|
13 Stitching Guide</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>This document introduces you to the panoramic stitching functionality. </p> |
|
15 <section id="GUID-3333CA2A-EF84-5E7B-B9BE-8FF00523897F-GENID-1-7-1-18-1-1-6-1-6-1-12-1-4-1-3-1-4-1-3-1-2-2"><title>Purpose</title> <p>Panoramic |
|
16 stitching involves combining a collection of images into a single image. </p> </section> |
|
17 <section><title>Panoramic stitching overview</title> <p>The panorama image |
|
18 is created by stitching a collection of several separate image into one large |
|
19 image. The panoramic stitching process is done by, </p> <ul> |
|
20 <li id="GUID-0DA59FD4-B817-5B51-8E83-F56FC42E1675"><p>image registration </p> </li> |
|
21 <li id="GUID-74941275-9681-51AB-B1FB-4F0829B47075"><p>cylindrical projection |
|
22 of images </p> </li> |
|
23 <li id="GUID-70E87CA6-B8BC-5CE9-A545-FC3782A81A69"><p>image blending. </p> </li> |
|
24 </ul> <p>The panoramic stitch can be done eihter interactively by using camera |
|
25 viewfinder, for tracking the camera movements or by stitching pre-captured |
|
26 images together. </p> <p><b>Introduction |
|
27 about the panoramic stitching</b> </p> <p>The <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> stitches |
|
28 a set of images into a single panorama image. The input to <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> is |
|
29 a collection of high resolution images together with some guidance on the |
|
30 relative positioning between the images expressed by <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita"><apiname>CPanoramaTransform</apiname></xref> instances. </p> <p>For |
|
31 the panorama creation, the most common use is rendering a full size panorama |
|
32 image to the device file system. </p> <p>The high level steps to use <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> are |
|
33 shown below: </p> <ul> |
|
34 <li id="GUID-EF02A22B-B4B1-5E97-97E7-F09DE26DA93A"><p>To construct <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref>, |
|
35 use <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-39BE88C3-C617-3AF8-A13D-CEC60AE798B1"><apiname>CImagePanorama::NewL()</apiname></xref> which loads the image panorama |
|
36 plugin. </p> </li> |
|
37 <li id="GUID-690408AF-782D-5E67-93BC-238EBCBD0C20"><p>To initialise <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref>, |
|
38 use <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-B6D24921-92B8-3FD8-B666-91C56E1E7984"><apiname>CImagePanorama::InitialiseL()</apiname></xref>. </p> </li> |
|
39 <li id="GUID-3E167564-6974-571E-99A0-196A5A18133D"><p>To correct the lens |
|
40 parameter use <xref href="GUID-90D79D23-97BC-3EE5-98DD-594DF6EFA0EE.dita"><apiname>TPanoramaLens</apiname></xref>. You need to correct the lens |
|
41 for panorama stitching quality. The lens parameters are camera specific. </p> </li> |
|
42 <li id="GUID-93217AEB-2AC5-5CCC-B5EE-36E8B99BAA85"><p>To add images to <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref>, |
|
43 use <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-B6591C30-F990-3D75-B9F3-922D41A5F1A1"><apiname>CImagePanorama::AddFileL()</apiname></xref>,<xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-19FBD32E-9B1F-38B0-963A-B361737818D2"><apiname>CImagePanorama::AddBufferL()</apiname></xref> or <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-66509DE8-2DBA-3FE0-8495-32E4256FA939"><apiname>CImagePanorama::AddImageL()</apiname></xref>, providing a hint on relative positioning or translation of the images through <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita"><apiname>CPanoramaTransform</apiname></xref>. |
|
44 This transform only needs to be approximate. </p> </li> |
|
45 <li id="GUID-B445F73C-2910-56DE-B03D-2637ECED0963"><p>To make the stitched |
|
46 image available call <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-A098A70C-050C-3592-BC37-E849A81890F2"><apiname>CImagePanorama::RenderL()</apiname></xref>. </p> </li> |
|
47 <li id="GUID-B68A2C77-F19A-5999-82C1-F433269DAACB"><p>The <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> instance |
|
48 can then be deleted. </p> </li> |
|
49 </ul> <p><b> Introduction |
|
50 about the CVFTracker</b> </p> <p> <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> is used to |
|
51 track viewfinder images to aid in capturing a panorama. The usage of <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> are |
|
52 demonstrated as follows: </p> <ul> |
|
53 <li id="GUID-3496F712-4FCD-5E89-BFEE-5AA6A22A1DA0"><p>The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> output |
|
54 is used for providing feedback and guidance to you, on how to move the camera |
|
55 while capturing a panorama. </p> </li> |
|
56 <li id="GUID-BDBC8A06-B2F8-507C-81F7-E2F344A94FEA"><p>The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> is |
|
57 used as an aid for the stitching process in the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref>. |
|
58 The input to the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> is a rapid flow of raw images |
|
59 from the viewfinder of the camera. The output is the movement of the camera. </p> </li> |
|
60 </ul> <p>The high level steps to use the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> are |
|
61 shown below: </p> <ul> |
|
62 <li id="GUID-5C25D0C8-49E1-5514-A90C-2B8A026D20CC"><p>To create <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref>, |
|
63 use the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AE92A41F-388D-338C-A80E-C0B16DF3BDDC"><apiname>CVFTracker::NewL()</apiname></xref>. The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AE92A41F-388D-338C-A80E-C0B16DF3BDDC"><apiname>CVFTracker::NewL()</apiname></xref> is |
|
64 used to load the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> plugin. </p> </li> |
|
65 <li id="GUID-ECE3D707-B871-5EC5-A04D-CA2A632BECC6"><p>To initialise <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref>, |
|
66 use <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-5E441486-3333-3B4F-81F3-3A86AE541CF8"><apiname>CVFTracker::InitialiseL()</apiname></xref>. </p> </li> |
|
67 <li id="GUID-54FEF93A-68BB-5EFB-8DE4-21F6562DCF11"><p>To reset <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref>, |
|
68 use <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AE707DEA-4747-3A1A-8C6F-8163F1DF0584"><apiname>CVFTracker::Reset()</apiname></xref>. </p> </li> |
|
69 <li id="GUID-32F88242-4EDD-54C7-8D7A-574015A197F4"><p>To perform the image |
|
70 registration, use <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AB58BBEB-5EAE-3E2A-A94E-F59334402A2B"><apiname>CVFTracker::RegisterImageL()</apiname></xref>. </p> </li> |
|
71 <li id="GUID-01DDC476-9596-55A1-B296-13877DB41B67"><p>To destroy the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref>, |
|
72 use <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-C2B64F7D-04D8-324A-BD84-C588503881BC"><apiname>CVFTracker::~CVFTracker()</apiname></xref>. </p> </li> |
|
73 </ul> <p><b>Camera |
|
74 requirements </b> </p> <p>The camera requirements for the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> and <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> are |
|
75 as follows, </p> <ul> |
|
76 <li id="GUID-C83A6919-C7BB-55C9-9D60-80EDAE0D4458"><p>The camera must provide |
|
77 low resolution images (in the order of 160 by 120 up to 320 by 240 resolution) |
|
78 as the raw format at a high frame rate to the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> and |
|
79 high resolution captured images to the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref>. </p> </li> |
|
80 <li id="GUID-EF41F660-AAEE-5D31-A014-FD6C39C42C5E"><p>For the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref>, |
|
81 it is better to have good frame rate than to have high resolution input images. </p> </li> |
|
82 <li id="GUID-810B06D2-D45F-5E7C-BC62-88AEE0B0A071"><p>The use of large <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> images |
|
83 can cause a lower frame rate on slow devices, and do not give accurate tracking |
|
84 for the view finder. </p> </li> |
|
85 <li id="GUID-DA5C3ED7-550D-5E4E-AD5A-E9119A56D8FB"><p>The optimal size of |
|
86 images is a tradeoff between the panorama quality and the time for rendering |
|
87 the panorama. </p> </li> |
|
88 </ul> </section> |
|
89 <section><title>How to use Panoramic Stitching</title> <p>This section contains |
|
90 some code snippets to show, how Panoramic stitching is accessed in several |
|
91 situations. </p> <p><b>Basic |
|
92 stitching </b> </p> <p>The basic stitching is demonstrated by a simple example |
|
93 of stitching four JPEG images into a single JPEG image providing an approximate |
|
94 translation between each image: </p> <p> </p> <codeblock id="GUID-304B7755-B05B-5BAE-884A-44A0500ABF37" xml:space="preserve"> |
|
95 |
|
96 TSize imageSize(1200, 1000); |
|
97 |
|
98 TDirection direction = EPanoramaDirectionRight; |
|
99 |
|
100 //Lens parameters or internal camera characteristics should be available for the |
|
101 //specific camera module in use. Here we use default values. |
|
102 TPanoramaLens lens; |
|
103 |
|
104 //Create transform. A transform is an approximate offset between each image. |
|
105 CPanoramaTransform* panTrans = CPanoramaTransform::NewL(); |
|
106 CleanupStack::PushL(panTrans); |
|
107 |
|
108 //Create panorama object.This stitches the individual images together. |
|
109 CImagePanorama* panImage = CImagePanorama::NewL(); |
|
110 CleanupStack::PushL(panImage); |
|
111 |
|
112 //Create panorama engine and set the lens and size |
|
113 panImage->InitializeL(imageSize, lens, direction); |
|
114 |
|
115 //Each file added is provided with an approximate translation. |
|
116 //In this case there are 4 images. |
|
117 panTrans->SetTranslationL(TPoint(0, 0), imageSize); |
|
118 panImage->AddFileL(KTestFileName1, *panTrans); |
|
119 |
|
120 panTrans->SetTranslationL(TPoint(900, -30), imageSize); |
|
121 panImage->AddFileL(KTestFileName2, *panTrans); |
|
122 |
|
123 panTrans->SetTranslationL(TPoint(900, 60), imageSize); |
|
124 panImage->AddFileL(KTestFileName3, *panTrans); |
|
125 |
|
126 panTrans->SetTranslationL(TPoint(400, -30), imageSize); |
|
127 panImage->AddFileL(KTestFileName4, *panTrans); |
|
128 |
|
129 //The image size can be obtained before rendering (if required) |
|
130 TSize size; |
|
131 panImage->CurrentImageSizeL(size); |
|
132 |
|
133 //view the output image |
|
134 panImage->RenderL(KTestBSOutputFileName); |
|
135 |
|
136 CleanupStack::PopAndDestroy(2); //panTrans, panImage |
|
137 |
|
138 </codeblock> <p>The main steps for using <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> are |
|
139 as follows, </p> <ol id="GUID-D6872BA3-A3DF-566A-83AF-527870CBE997"> |
|
140 <li id="GUID-FB378114-769F-5404-BD20-8886D538191F"><p>create <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> </p> </li> |
|
141 <li id="GUID-D8A28AFC-4D37-59C4-91D9-92F4898F2302"><p>some approximate transform |
|
142 information for each image pair </p> </li> |
|
143 <li id="GUID-146D95D7-14DE-57CA-96DA-45959EB895A4"><p>add each images to <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> </p> </li> |
|
144 <li id="GUID-FF479A52-24E3-5D0B-A821-44127DA5B60C"><p>render the output (for |
|
145 example to the file) </p> </li> |
|
146 <li id="GUID-0ADBEE3F-AA60-5787-92A0-C421D4EA8731"><p>delete the objects used. </p> </li> |
|
147 </ol> <p> <b>Note:</b> The following points must be noted by you: </p> <ul> |
|
148 <li id="GUID-D3EB4190-4B2B-5760-8E6C-D19DAFF439DF"><p>The lens parameters |
|
149 are not resolution dependant. It is enough to calibrate once for each camera |
|
150 model and no need to recalibrate for each resolution. For best accuracy, use |
|
151 the highest resolution possible when calibrating with a calibration tool. </p> <p>The |
|
152 approximate translations in x co-ordinate and y co-ordinate ( as dx, dy) must |
|
153 be compliant with the value of direction. </p> </li> |
|
154 </ul> <p><b>A |
|
155 camera application example</b> </p> <p>The <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> is |
|
156 used in a camera application. The example is more complicated than the previous |
|
157 example. In this example <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> provides the approximate |
|
158 transform between the captured images. </p> <p><b>Viewfinder |
|
159 image tracking </b> </p> <p>The <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> generates |
|
160 panorama images. The application starts the process and then use the camera |
|
161 for capturing the images. The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> will give an indication |
|
162 when to capture the high resolution images, which will later be stitched into |
|
163 a panorama image. </p> <p>The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> plays an important |
|
164 role for getting the camera movement. The high level steps to use the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> in |
|
165 the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> for a camera application, are shown |
|
166 below: </p> <ol id="GUID-B6357C9E-1510-53C8-856B-2C06C7A6A69C"> |
|
167 <li id="GUID-54C90419-08DE-5406-BBF1-37C0B59FCA26"><p>To create the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> object |
|
168 and load the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> plugin, use <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AE92A41F-388D-338C-A80E-C0B16DF3BDDC"><apiname>CVFTracker::NewL()</apiname></xref>. </p> </li> |
|
169 <li id="GUID-D3E16606-ED81-5702-9F4F-9B19754D4768"><p>To create <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> object |
|
170 and load the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> plugin, use <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-39BE88C3-C617-3AF8-A13D-CEC60AE798B1"><apiname>CImagePanorama::NewL()</apiname></xref>. </p> </li> |
|
171 <li id="GUID-E5C6B072-64FE-554F-BAC4-8850E15B841D"><p>To create the <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita"><apiname>CPanoramaTransform</apiname></xref> object |
|
172 and set or get the values, use the <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita#GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA/GUID-ADB1D55B-CEA7-3151-B6E2-14F165F8BB9F"><apiname>CPanoramaTransform::NewL()</apiname></xref>. </p> </li> |
|
173 <li id="GUID-FD68A411-E492-5492-88FD-E7A7307113F7"><p>To create and set the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref>, <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref>, |
|
174 and <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita"><apiname>CPanoramaTransform</apiname></xref> functions for the Image Processor |
|
175 Adaptation Plug-in objects, use <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-5E441486-3333-3B4F-81F3-3A86AE541CF8"><apiname>CVFTracker::InitialiseL()</apiname></xref> and <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-B6D24921-92B8-3FD8-B666-91C56E1E7984"><apiname>CImagePanorama::InitialiseL()</apiname></xref> respectively.</p> </li> |
|
176 <li id="GUID-A605F836-474D-55D4-A326-9AC8B0F8F86B"><p>To get a translation |
|
177 value from a viewfinder image, register an image by using <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AB58BBEB-5EAE-3E2A-A94E-F59334402A2B"><apiname>CVFTracker::RegisterImageL()</apiname></xref>. |
|
178 This will return translation information as a CPanoramaTransform object. </p> </li> |
|
179 <li id="GUID-8E6E35D9-B20A-5BA2-987F-1A3447DEA146"><p>Check the right time |
|
180 to capture the next image by using <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-945FF7AD-31E5-3C6A-AD89-F1A5FC225B9D"><apiname>CVFTracker::IsTimeToCapture()</apiname></xref>. </p> </li> |
|
181 <li id="GUID-A490A649-B910-5E1C-B317-EC5627547EF7"><p>Reset the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> for |
|
182 the next image, using <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita#GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352/GUID-AE707DEA-4747-3A1A-8C6F-8163F1DF0584"><apiname>CVFTracker::Reset()</apiname></xref>. </p> <p>In order |
|
183 to capture many images to be stitched into a single panorama image, repeat |
|
184 the steps 5, 6 and 7. </p> </li> |
|
185 </ol> <fig id="GUID-7F48B2F5-D65B-52EC-8412-F3F56A5EE8E8"> |
|
186 <image href="GUID-470FAFE8-2246-5E91-9F01-6CC95F975E54_d0e505754_href.jpg" placement="inline"/> |
|
187 </fig> <p><b>Panorama |
|
188 stitching </b> </p> <p>The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> helps to decide when |
|
189 to capture each of the full resolution images using the camera. The images |
|
190 can then be passed to CImagePanorama and the stitching is done. The high level |
|
191 steps to do panorama stitching are listed below: </p> <ol id="GUID-763005A3-4098-534F-9CA1-E2F8654C95BD"> |
|
192 <li id="GUID-6866E73F-F1F7-53C8-BA64-8AF448318C53"><p>Capture the next image |
|
193 using the camera, then add the image to the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> by |
|
194 using <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-66509DE8-2DBA-3FE0-8495-32E4256FA939"><apiname>CImagePanorama::AddImageL()</apiname></xref> or <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-201D0607-2D25-3B1D-B449-7A61419BB0C8"><apiname>CImagePanorama::AddFileL</apiname></xref>, |
|
195 passing in the <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita"><apiname>CPanoramaTransform</apiname></xref> object obtained from |
|
196 the CVFTracker. </p> </li> |
|
197 <li id="GUID-BC35AEEF-206E-5830-909E-07F645C2E063"><p>When all images have |
|
198 been captured you can render the stitched image to file, image buffer, CFbsBitmap |
|
199 or image frame using <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita#GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4/GUID-A098A70C-050C-3592-BC37-E849A81890F2"><apiname>CImagePanorama::RenderL()</apiname></xref>. </p> </li> |
|
200 </ol> <fig id="GUID-B5F7149F-1FB9-535E-9212-7C9E23B9347B"> |
|
201 <image href="GUID-A8C80AA1-42CF-5866-B223-FCE1AEC9DF63_d0e505804_href.jpg" placement="inline"/> |
|
202 </fig> <p><b>User Interface</b> </p> <p>Provide a good user interface (UI) application |
|
203 for the <xref href="GUID-4DBD1F07-42C5-3CD7-B809-A391F315E0D4.dita"><apiname>CImagePanorama</apiname></xref> is crucial. An example of UI design |
|
204 is described below, which gives you a robust and easy application for generating |
|
205 panorama images. </p> <p><b>How |
|
206 to shoot a panorama </b> </p> <p>The steps to be followed for shooting a panorama |
|
207 images: </p> <ol id="GUID-8FD3D305-BEAF-5414-BD49-5728C2504256"> |
|
208 <li id="GUID-92642922-D0A0-57CD-80A6-03722941E52C"><p>You need to press the |
|
209 start button of the camera and need to sweep the camera towards the wanted |
|
210 scene. </p> <p> <b>Note:</b> You must try not to move the mobile phone, but |
|
211 only rotate it. You see in the below diagram the camera is sweep in a clockwise |
|
212 direction from left-to-right. The rotation is made around the imagined axis |
|
213 through mobile (axis of rotation in the image). A panorama image covers approximately |
|
214 a 100 degree field of view. </p> <fig id="GUID-8562E235-6D10-5097-A888-E27EE6D4E498"> |
|
215 <image href="GUID-7B3578A0-7E2E-508A-A355-A39AEE0307AD_d0e505841_href.jpg" placement="inline"/> |
|
216 </fig> </li> |
|
217 <li id="GUID-16CA0CFB-9D17-573C-9D7B-FEDBCFF4044C"><p> <b>Application Start</b> </p> <p>When |
|
218 you launch the application the UI appears as shown in the below diagram. </p> <fig id="GUID-4A6082E2-1B7F-5A48-8FC5-7BC2786987B7"> |
|
219 <image href="GUID-0E55E007-913C-56DA-8BEF-7EC00FFCCE51_d0e505857_href.jpg" placement="inline"/> |
|
220 </fig> <p>Here the screen area shows the viewfinder image. When you sweep |
|
221 the mobile, several images are captured and then the images are stitched to |
|
222 create a panorama image. </p> </li> |
|
223 <li id="GUID-FE8D49DB-26CC-5546-A05D-B46045894313"><p> <b>Capture a panorama |
|
224 image during tracking</b> </p> <p>When you choose to capture a panorama image |
|
225 the UI changes, which is shown in the below diagram. </p> <fig id="GUID-930C8F54-4C13-50AC-B700-9D889FFE9DC7"> |
|
226 <image href="GUID-9AB5481B-C321-56C9-937D-2397AA80DE8E_d0e505876_href.jpg" placement="inline"/> |
|
227 </fig> <p>In the above diagram you see three different boxes named 1, 2 and |
|
228 3 which represent the position of the camera. The blue box representation |
|
229 changes according to the rotation of the mobile phone. </p> <p>The boxes shown |
|
230 in the above diagram is for illustrative purpose, so that it can be down scaled |
|
231 for viewfinder image size. The total panorama coverage area box is estimated |
|
232 by the number of images for capturing and the overlapping area size. </p> <p>The |
|
233 code snippets below shows the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> tracking. </p> <codeblock id="GUID-73381F9D-53D9-505A-888D-464A83B0A352" xml:space="preserve"> |
|
234 |
|
235 _LIT(KFileOutput, "c:\\ICLExample\\viewfinder%d.mbm"); |
|
236 _LIT(KFileCapturedImage, "c:\\ICLExample\\pancapture%d.jpg"); |
|
237 TInt i = 0; |
|
238 |
|
239 TSize imageSize(1200,1000); |
|
240 CFbsBitmap* bmp = new (ELeave) CFbsBitmap; |
|
241 CleanupStack::PushL(bmp); |
|
242 |
|
243 // get 1st viewfinder image from camera into bmp (detail excluded) |
|
244 TSize bmpSize = bmp->SizeInPixels(); |
|
245 |
|
246 CPanoramaTransform* panTrans = CPanoramaTransform::NewL();//create panorama transoform |
|
247 CleanupStack::PushL(panTrans); |
|
248 |
|
249 CVFTracker* vfTracker = CVFTracker::NewL(); //create VFTracker and load the plugin |
|
250 CleanupStack::PushL(vfTracker); |
|
251 |
|
252 vfTracker->InitializeL(bmpSize); //Create VFTracker and set size |
|
253 |
|
254 CImagePanorama* panImage = CImagePanorama::NewL(); //create CImagePanorama object |
|
255 CleanupStack::PushL(panImage); |
|
256 |
|
257 TDirection direction = EPanoramaDirectionRight; //assign direction |
|
258 |
|
259 // Lens parameters or internal camera characteristics should be available for the |
|
260 // specific camera module in use. Here we use default values. |
|
261 TPanoramaLens lens; |
|
262 panImage->InitializeL(imageSize, lens, direction); //initialise size, lens, direction and create panorama engine |
|
263 |
|
264 // get the first captured image from the camera as a starting point - its name is given in capturedFileName |
|
265 TFileName capturedFileName; |
|
266 capturedFileName.Format(KFileCapturedImage(),i); |
|
267 panImage->AddFileL(capturedFileName, *panTrans); //add the captured image |
|
268 |
|
269 do |
|
270 { |
|
271 // give the next camera viewfinder image to the tracker (details ommitted) |
|
272 vfTracker->RegisterImageL(*bmp, *panTrans); // register viewfinder image |
|
273 |
|
274 // check if we have a good overlap with the previous image |
|
275 if(vfTracker->IsTimeToCapture(direction, KPanoramaDefaultOverlap)) |
|
276 { |
|
277 // capture the next image from the camera (details ommitted) |
|
278 capturedFileName.Format(KFileCapturedImage(),i); |
|
279 |
|
280 panImage->AddFileL(capturedFileName, *panTrans); //add the captured image |
|
281 vfTracker->Reset(); //reset the VFTracker object |
|
282 } |
|
283 if ( err != KErrNone ) // some termination condition usually a signal from user |
|
284 { |
|
285 // no more viewfinder images |
|
286 break; |
|
287 } |
|
288 } |
|
289 while (1); |
|
290 panImage->RenderL(KTestVFTOutputFileName); // render the stitched image |
|
291 CleanupStack::PopAndDestroy(4,bmp); //panTrans, vfTracker, panImage, bmp |
|
292 </codeblock> <p>The <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> is passed each viewfinder |
|
293 images which it checks and determines whether it is right time to capture |
|
294 the next image. In return it provides translation information <codeph>CPanoramaTransform::GetTranslation()</codeph> which |
|
295 indicates the shift of the current viewfinder image. </p> <p>The extracted |
|
296 information is used to draw the blue rectangle on the screen. If it is time |
|
297 to capture, then it triggers the capturing function and restarts the <xref href="GUID-0D12EA24-3BF5-3BEA-B0EA-CEB89D49D352.dita"><apiname>CVFTracker</apiname></xref> again |
|
298 for next image. </p> <p> <b>Note:</b> The box representation is used in the |
|
299 UI, to help you to take better panorama images. In addition a vibration effect |
|
300 can be used to provide additional feedback on when to capture an image. For |
|
301 example, when you sweep the mobile phone, it is in tracking mode so it vibrates. |
|
302 When the mobile phone is ready to capture, the vibration stops to let you |
|
303 know that it must be static for capturing an accurate second image. Then when |
|
304 it vibrates again, you must rotate the mobile and until it stop. </p> </li> |
|
305 <li id="GUID-C7848E42-74B4-56D2-BB7B-2F20A4D30D32"><p> <b>User interface updating |
|
306 details </b> </p> <p>The UI design detail is shown in step by step process. |
|
307 They are as follows: </p> <ul> |
|
308 <li id="GUID-99D23225-ECF9-5A34-ADAA-4E0A2326D768"><p>The total panorama coverage |
|
309 area is divided into four different image areas: </p> <fig id="GUID-0808E657-6313-510C-9EB6-F4D49722229B"> |
|
310 <image href="GUID-023D30F0-C1E8-5E09-92AD-C5A7963DCF70_d0e505937_href.jpg" placement="inline"/> |
|
311 </fig> </li> |
|
312 <li id="GUID-D06A8B59-81EE-5420-A3AE-FB036B7CE3F4"><p>When you choose to capture |
|
313 a panorama image the following steps are performed. The first image is captured |
|
314 at position 0. The UI looks as follows: </p> <fig id="GUID-A17F50EC-3241-56CA-B96A-59515EAF161B"> |
|
315 <image href="GUID-C2D99C88-09C7-55FA-AF95-3F689BA27484_d0e505947_href.jpg" placement="inline"/> |
|
316 </fig> </li> |
|
317 <li id="GUID-BF4A2D67-EF8D-5F72-B2C2-9DC79E319023"><p>When you rotate the |
|
318 mobile phone clockwise, the blue box moves to the right using the translation |
|
319 information from <xref href="GUID-27BD164A-9283-3BE0-A0BF-A475539D86EA.dita"><apiname>CPanoramaTransform</apiname></xref>. At the same time the |
|
320 vibrator is set on to give direct feedback for the tracking process. When |
|
321 the blue box and the grey box (which represent the position to capture the |
|
322 next image) coincide, the blue box turns into a filled blue box and the vibrator |
|
323 stops. You then known that the next image is captured. At this moment the |
|
324 camera must be steady. </p> <p>After second image is captured the blue box |
|
325 is moving again and vibrator is set-on. The UI looks as follows: </p> <fig id="GUID-C6E583BB-EE47-52EE-BBFB-D7EE37156C12"> |
|
326 <image href="GUID-B985B750-9B42-55ED-B7E4-41B06B44C365_d0e505964_href.jpg" placement="inline"/> |
|
327 </fig> <p>Again, you rotate the mobile clockwise until the two boxes coincide |
|
328 and vibrator stops; third image then captured. After this, the UI looks as |
|
329 follows: </p> <fig id="GUID-FD9D81DA-E675-5C9C-BA6E-4E7DCE6F46D9"> |
|
330 <image href="GUID-9E12593C-38EF-5052-A2E8-0AB25EEFF4D0_d0e505972_href.jpg" placement="inline"/> |
|
331 </fig> <p>You rotate the mobile phone until the boxes coincide and the fourth |
|
332 (last) image is captured. </p> <p> <b>Note:</b> If the mobile phone rotation |
|
333 deviates from chosen (clockwise) direction or translates up and down, the |
|
334 blue box indicates this, and you must correct the mobile phone for the wrong |
|
335 movement. </p> <p>At this point the stitched image can be saved or you can |
|
336 reset the camera, to create another panorama image: </p> <fig id="GUID-1A527BEA-0C50-5910-9525-75336C02B2C9"> |
|
337 <image href="GUID-8E2303E9-DB60-5F38-A4D4-8BF8F7A1EF9F_d0e505989_href.jpg" placement="inline"/> |
|
338 </fig> </li> |
|
339 </ul> </li> |
|
340 </ol> <p><b>Camera |
|
341 calibration </b> </p> <p>In order to produce good panorama images, the internal |
|
342 characteristics of the camera is calibrated by the <xref href="GUID-E361A378-76EB-36C9-A949-A5D31D4D1C4C.dita"><apiname>TPanoramaLens()</apiname></xref>. |
|
343 The lens parameter such as the distance, the focal length, the principal point, |
|
344 the skew, the width and the height are called the intrinsic parameters. </p> <p>The |
|
345 camera module supplier should be able to provide this information or there |
|
346 are a number of tools to get the camera parameters. A free tool that can be |
|
347 used is the calibration functions in <xref href="http://en.wikipedia.org/wiki/Opencv" scope="external">OpenCV</xref>. Typically these tools need an input of images |
|
348 of a special reference pattern, for example a checker board like grid, photographed |
|
349 from many directions. From that the tools automatically generate all the desired |
|
350 lens parameters. </p> </section> |
|
351 </conbody></concept> |