Sean 的个人资料Sean McLeod照片日志列表更多 ![]() | 帮助 |
Sean McLeod10月8日 Live Photo Gallery People TagsI’ve used the tagging feature in the original Windows Vista Photo Gallery and the Windows Live Photo Gallery versions for tagging people in photos and the location of the photo. The latest version of Windows Live Photo Gallery now includes a specific ‘People’ category separate from the generic tags category for identifying people in photos. In addition it includes a feature to automatically identify faces in photos and to associate the ‘People’ tags with specific faces in the photo. The sample below taken from the Windows Live Photo blog shows the new face tagging features. You can also manually draw a rectangle over a face and tag it if the Photo Gallery doesn’t automatically detect the face.
One issue I’ve noticed is that the new people tags aren’t indexed by Windows Search. I often use Windows Search to search for photos based on my people and location tags and the new people tags aren’t found. So at the moment you have to search or filter photos based on the new people tags in Live Photo Gallery itself. I took a look at the XMP meta-data that is stored by the new people tagging feature in the associated photos. In the snippet below you can see how the rectangular region for the relevant face is stored if there is one plus the PersonDisplayName. There are APIs in WIC plus associated .Net wrappers in the .Net Framework that allow you to read this meta-data so you could make use of the rectangular regions in your own application that may want to display photos and show the tagged faces etc. <rdf:Description xmlns:prefix0="http://ns.microsoft.com/photo/1.2/"> <prefix0:RegionInfo> <rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <prefix1:Regions xmlns:prefix1="http://ns.microsoft.com/photo/1.2/t/RegionInfo#"> <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:li> <rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <prefix2:Rectangle xmlns:prefix2="http://ns.microsoft.com/photo/1.2/t/Region#">0.209985, 0.526367, 0.167401, 0.111328</prefix2:Rectangle> <prefix3:PersonDisplayName xmlns:prefix3="http://ns.microsoft.com/photo/1.2/t/Region#">Sarah McLeod</prefix3:PersonDisplayName> </rdf:Description> </rdf:li> <rdf:li> <rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <prefix4:Rectangle xmlns:prefix4="http://ns.microsoft.com/photo/1.2/t/Region#">0.430250, 0.148438, 0.284875, 0.189453</prefix4:Rectangle> <prefix5:PersonDisplayName xmlns:prefix5="http://ns.microsoft.com/photo/1.2/t/Region#">Gwen De Roubaix</prefix5:PersonDisplayName> </rdf:Description> </rdf:li> <rdf:li> <rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <prefix6:PersonDisplayName xmlns:prefix6="http://ns.microsoft.com/photo/1.2/t/Region#">Marcelle De Roubaix</prefix6:PersonDisplayName> </rdf:Description> </rdf:li> </rdf:Bag> </prefix1:Regions> </rdf:Description> </prefix0:RegionInfo> </rdf:Description> The following snippet shows the XMP meta-data that is stored if you tag one of your Messenger contacts as a People tag. <rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:prefix0="http://ns.microsoft.com/photo/1.2/"> <prefix0:RegionInfo> <rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <prefix1:Regions xmlns:prefix1="http://ns.microsoft.com/photo/1.2/t/RegionInfo#"> <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:li> <rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <prefix2:PersonDisplayName xmlns:prefix2="http://ns.microsoft.com/photo/1.2/t/Region#">gerhard</prefix2:PersonDisplayName> <prefix3:PersonEmailDigest xmlns:prefix3="http://ns.microsoft.com/photo/1.2/t/Region#">89C386678731AB3D7DEE0E14E11E633387FBDBCD</prefix3:PersonEmailDigest> <prefix4:PersonLiveIdCID xmlns:prefix4="http://ns.microsoft.com/photo/1.2/t/Region#">8765613456339678115</prefix4:PersonLiveIdCID> </rdf:Description> </rdf:li> </rdf:Bag> </prefix1:Regions> </rdf:Description> </prefix0:RegionInfo> </rdf:Description> And lastly a snippet showing how the regular tags which are indexed by Windows Search are stored, basically in a <dc:subject> element and in a <MicrosoftPhoto:LastKeywordXMP> element. <rdf:Description xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:subject> <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:li>Party</rdf:li> <rdf:li>People/Sarah McLeod</rdf:li> </rdf:Bag> </dc:subject> </rdf:Description> <rdf:Description xmlns:MicrosoftPhoto="http://ns.microsoft.com/photo/1.0"> <MicrosoftPhoto:LastKeywordXMP> <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:li>Party</rdf:li> <rdf:li>People/Sarah McLeod</rdf:li> </rdf:Bag> </MicrosoftPhoto:LastKeywordXMP> </rdf:Description> 10月7日 Bitmap snapshots of WPF VisualsRecently I needed to create a bitmap of some WPF controls to be used in another program. Doing a quick search turned up references to the RenderTargetBitmap class in WPF with sample code along the lines of: RenderTargetBitmap bmp = new RenderTargetBitmap((int)element.Width, (int)element.Height, 96, 96, PixelFormats.Pbgra32); bmp.Render(element); However if the WPF control had a margin then the rendered bitmap had transparent pixels for the margin area. As an example here is a button inside a StackPanel with a margin applied. And the following is the bitmap that is created via the sample code above: Doing some more searching turned up the following code which creates a VisualBrush from the target Visual and then renders that into a DrawingVisual and then finally uses RenderTargetBitmap to take a snapshot of the DrawingVisual. Using this approach the margins are ignored and the bitmap only consists of the target WPF control/visual as shown below: void CreateBitmapFromVisual(Visual target, string filename) { if (target == null) return; Rect bounds = VisualTreeHelper.GetDescendantBounds(target); RenderTargetBitmap rtb = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96, 96, PixelFormats.Pbgra32); DrawingVisual dv = new DrawingVisual(); using (DrawingContext dc = dv.RenderOpen()) { VisualBrush vb = new VisualBrush(target); dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size)); } rtb.Render(dv); PngBitmapEncoder png = new PngBitmapEncoder(); png.Frames.Add(BitmapFrame.Create(rtb)); using (Stream stm = File.Create(filename)) { png.Save(stm); } } 6月8日 Geeks and Fast JetsI was approached recently to help develop some Flight Test Instrumentation (FTI) for a Hawker Hunter jet to be used during a test pilot course involving high angle of attack manoeuvres and spinning. The following data needed to be recorded:
In addition to recording all the data listed above they also wanted to display a subset of the data in the cockpit as an aid for spin recovery. SensorsAoA and sideslip - basically small weather vanes that act as potentiometers were ordered and then physically mounted on a pitot/static boom which was then mounted on the front of the Hawker Hunter's nose. One minor issue was finding a route for the wires from the vanes to the PC in the avionics bay that didn't have to pass through the cockpit's pressure capsule. Attitude - ordered an Attitude and Heading Reference System (AHRS) from Crossbow that uses solid state sensors and outputs at 25Hz. Ideally the AHRS needs to be mounted as close as possible to the centre of gravity. Luckily the avionics bay is fairly close to the centre of gravity, just slightly forward but there was space to mount it quite easily and definitely on the centre line of the aircraft. GPS - the Crossbow AHRS also includes a built-in GPS which it uses for aiding it's attitude solution and also outputs standard NMEA data via a second serial port. Mounted the GPS antenna on the spine of the aircraft behind the cockpit with a fairly short vertical run for the GPS antenna cable to the avionics bay. Air data - used an existing unit we had from MGL Avionics that we had been using on the Ikarus C-42. Wasn't ideal since it's maximum indicated airspeed is 217kt which means it was maxed out a lot of the time. However the stall speed was generally below 217kt so it did provide useful data during the stall and spin. Control positions - we ordered 3 linear transducers which basically have a shaft that moves in and out and it acts as a potentiometer. They were mounted and attached to the 3 control rods that pass through the spine of the aircraft behind the cockpit. It was again a fairly short straight drop down into the avionics for the wires. PCWe needed a PC on fairly short notice that was fairly ruggedized in terms of handling vibration and also fairly cold operating temperatures since it was going to be mounted in an unpressurized and unheated avionics bay and the spins would normally be starting at 35,000ft. The only real change we made to the embedded PC we found was to replace the hard drive with a CF card and to run everything off the CF card. In addition to the high dynamics during the spin plus regular vibration causing problems for a normal hard drive most hard drives aren't rated to operate above 10,000ft pressure altitude anyway. We used XP Embedded and it's Enhanced Writer Filter (EWF) to turn the system partition into a read-only volume so it couldn't be corrupted during power down since the power was simply going to switched off with no proper shutdown. The data from the sensors was logged to a separate partition on the CF card. The embedded PC also came with 4 onboard RS232 ports which we needed in order to connect to all the RS232 based sensors (AHRS, GPS, air data). To read the analog data from the AoA, sideslip and control position sensors we installed an A/D card into the single PCI slot. DisplayFor the in cockpit display of 'spinning panel' which mainly consisted of displaying the AoA and sideslip angles plus the control positions we initially developed a Pocket PC application which was connected to the embedded PC via an RS232 connection. However after some concerns regarding it's sunlight readability and some concerns about physically mounting it in the cockpit the Pocket PC was only used on 2 initial test flights. We then bought a 6" LCD which was rated at 1200nits for sunlight readability and removed the gunsight to mount the LCD in it's place on the student's side of the cockpit. The software for the 'spin panel' was then modified to run on the embedded PC that we were using for data capture and to connect it to the LCD using a VGA connection. The one issue or complication with the 'spin panel' display being mounted in the cockpit was the need to have wires passing through the pressure bulkhead from the avionics bay into the cockpit. Special bulkhead connectors have to be used in order to pass the wires through without causing a pressure leak. VideoAn SD based video camera recorder with a remote lens was mounted in the cockpit and used to capture video footage of the flight. PlaybackThe last part of the project involved the development of a playback system to take the captured data from the sensors and from the video camera and allow the data to be played back and analysed by the pilots and flight test engineers. The attitude data and air data are displayed as part of a standard Primary Flight Display (PFD). The spin panel display that is used in the cockpit is also rendered plus playback of the video. Lastly we have line graphs displaying the current, past and future data for each of the recorded parameters. All of the data including the video is synchronised during playback and can be paused, seeked and played back at different speeds, i.e. various slow motion and fast motion playback speeds. The playback application is a Windows Presentation Foundation (WPF) application and makes heavy use of the animation framework within WPF. And finally getting ready for the last of the 34 sorties on a glorious Cape Town winter's day. 1月23日 MapReduce implementation using C# genericsI came across the Google paper on MapReduce again the other day and decided to try a simple implementation using C# generics allowing you to specify specific types for the keys and values as opposed to being forced to use strings for all keys and values. The initial version doesn't include any automatic parallelism across multiple CPUs or clusters of machines. The core implementation below is only about 50-60 lines of code. I've also included sample map and reduce functions making use of this library and mirroring some of the sample applications mentioned in the Google paper.
12月31日 High Dynamic Range (HDR) Photo TestI started playing around with generating HDR photos. Here is one of my first attempts using our Pentax DSLR. I'm using a trial version of Photomatix to perform the HDR processing and tone mapping which is why you'll notice their watermark in the HDR image below. I set the auto-bracketing option on the camera to shoot a normal exposure, a -2 stop exposure and a +2 stop exposure. This is the resultant HDR image. Next up is the camera's normal exposure, so effectively what you would end up with if you weren't doing any HDR processing. Camera selected f/9.5 and 1/60 sec. Now the -2 stop image, so f/9.5 1/250 sec. And lastly the +2 stop image, so f/9.5 1/15 sec. 7月31日 Windows Desktop Search Powershell CmdletMicrosoft are introducing a new command line shell named PowerShell, previously known as Monad. The main difference between PowerShell and other shells like cmd, bash, ksh etc. is the pipelining and processing of objects as opposed to plain text.
I had previously used the Windows Desktop Search API to write a music browser and thought it would be useful to create a Windows Desktop Search Powershell cmdlet to allow users to query their search index from the command line. The results of the query can then be pipelined to further cmdlets to act on the results or to simply display the result set.
A more detailed write up with the source code available for download is available at CodeProject. 7月20日 Sedgefield Holiday
|
|||||||||
|
|