追記(2009/4/12): ステンレス製ボール+WebCamでやってみたw.
tumblrで見かけた「ストリートビュー車を作ってみた」からちょっと興味がわいたのでやってみた.
早速グーグル先生に相談.参考資料を用意.
参考: 全方位カメラのためのパノラマ画像展開(ありがとうございます)
参考には補正がいくつかのっていたがとりあえず難しい事は置いておいて勢いだけでやってみた.
QCPlugInのプロパティについて
@interface ExtensionForOmniDirectionalCameraPlugIn : QCPlugIn
{
}
@property(assign) id<QCPlugInInputImageSource> inputSourceImage;
@property(assign) id<QCPlugInOutputImageProvider> outputResultImage;
@end
QCPlugInのexecute:atTime: withArguments:
- (BOOL) execute:(id)context atTime:(NSTimeInterval)time withArguments:(NSDictionary*)arguments
{
idimage;
self.outputResultImage = nil;
if(image= self.inputSourceImage) {
if(![image lockBufferRepresentationWithPixelFormat:QCPlugInPixelFormatARGB8
colorSpace:[image imageColorSpace]
forBounds:[image imageBounds]]) {
return NO;
}
NSBitmapImageRep *p= [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:[image bufferPixelsWide]
pixelsHigh:[image bufferPixelsHigh]
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaFirstBitmapFormat
bytesPerRow:[image bufferBytesPerRow]
bitsPerPixel:0];
[p autorelease];
memcpy([p bitmapData], [image bufferBaseAddress], [image bufferBytesPerRow]*[image bufferPixelsHigh]);
NSUInteger T= 360*2;
NSUInteger R= [image bufferPixelsHigh] / 2;
NSBitmapImageRep *q= [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:T
pixelsHigh:R
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaFirstBitmapFormat
bytesPerRow:4*T
bitsPerPixel:0];
[q autorelease];
{
NSUInteger CX= [image bufferPixelsWide] / 2;
NSUInteger CY= [image bufferPixelsHigh] / 2;
NSUInteger i, j;
double ratio= T/360.0;
for(i= 0;i<T;i++) {
for(j=0; j<R; j++) {
double th= (i/ratio) * M_PI / 180.0 - M_PI;
NSUInteger x= (NSUInteger)(j * cos(th) + CX);
NSUInteger y= (NSUInteger)(j * sin(th) + CY);
NSColor *c= [p colorAtX:x y:y];
[q setColor:c atX:i y:R-j-1];
}
}
}
OutputImageProvider *provider = [[OutputImageProvider alloc] initWithBuffer:(void *)[q bitmapData]
withBytesPerRow:4*T
pixelFormat:QCPlugInPixelFormatARGB8
forBounds:NSMakeRect(0, 0, T, R)
colorSpaceRef:[image imageColorSpace]];
if(provider == nil)
return NO;
self.outputResultImage = provider;
[provider release];
}
[image unlockBufferRepresentation];
return YES;
}
上で出てきたOutputImageProvider関連
@interface OutputImageProvider : NSObject <QCPlugInOutputImageProvider>
{
void *_baseAddress;
NSUInteger _rowBytes;
NSString *_format;
NSRect _bounds;
CGColorSpaceRef _cgColorSpaceRef;
}
- (id)initWithBuffer:(void*)baseAddress
withBytesPerRow:(NSUInteger)rowBytes
pixelFormat:(NSString*)format
forBounds:(NSRect)bounds
colorSpaceRef:(CGColorSpaceRef)cgColorSpaceRef;
@end
@implementation OutputImageProvider
- (id)initWithBuffer:(void*)baseAddress
withBytesPerRow:(NSUInteger)rowBytes
pixelFormat:(NSString*)format
forBounds:(NSRect)bounds
colorSpaceRef:(CGColorSpaceRef)cgColorSpaceRef
{
if(self = [super init]) {
_baseAddress= baseAddress;
_rowBytes= rowBytes;
_format= [format retain];
_bounds= bounds;
_cgColorSpaceRef= cgColorSpaceRef;
}
return self;
}
- (void) dealloc
{
[_format release];
[super dealloc];
}
- (NSRect) imageBounds
{
return _bounds;
}
- (CGColorSpaceRef) imageColorSpace
{
return _cgColorSpaceRef;
}
- (NSArray*) supportedBufferPixelFormats
{
return [NSArray arrayWithObjects: _format,
nil];
}
- (BOOL) renderToBuffer:(void*)baseAddress
withBytesPerRow:(NSUInteger)rowBytes
pixelFormat:(NSString*)format
forBounds:(NSRect)bounds
{
memcpy(baseAddress, _baseAddress, _rowBytes*_bounds.size.height);
return YES;
}
@end
実際の映像なんだけど,参考にある画像をCropするとか,グーグル先生で適切なキーワードで調べてみるといくつか掲載されているページがでてくるのでそちらから拝借して試した.(権利関係があるだろうから掲載しないけど)これだけでも人間が見る分には(w)こまらないことがわかったりした.
自分で鏡等が用意できればそれで撮影して変換前後の掲載できるんだけどなw.
元ネタのようにステンレス製半球ミラーを買えば良いんだろうけどw.
0 件のコメント:
コメントを投稿