.-- --

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
スポンサー広告 comment(-) trackback(-)
.30 2013

Eigenでオペレータ演算子を使った行列の計算

こんにちわ。Uedaです。

今回はEigenでオペレータ演算子を使った行列の計算の紹介です。


Matrix3d m1 = Matrix3d::Random(3, 3);
Matrix3d m2 = Matrix3d::Random(3, 3);

Matrix3d m3 = m1 + m2;
Matrix3d m4 = m1 * m2;


直感的に実装できるので便利です。

計算結果
2013-05-30 17:40:33.783 TestEigen[3396:c07]
-0.999984, -0.082700, -0.905911
-0.736924, 0.065534, 0.357729
0.511211, -0.562082, 0.358593
2013-05-30 17:40:33.785 TestEigen[3396:c07]
0.869386, 0.661931, 0.059400
-0.232996, -0.930856, 0.342299
0.038833, -0.893077, -0.984604
2013-05-30 17:40:33.786 TestEigen[3396:c07]
-0.130599, 0.579231, -0.846510
-0.969920, -0.865321, 0.700028
0.550043, -1.455158, -0.626011
2013-05-30 17:40:33.787 TestEigen[3396:c07]
-0.885282, 0.224109, 0.804256
-0.642049, -0.868276, -0.373563
0.589327, 0.541352, -0.515106

以上です。
.29 2013

ORB特徴点を表示してみた

こんにちわ。Uedaです。

前回, iphone側で動画像を取得して, それをOpenCVで扱える形に変換するところまで紹介しました。
今回はとりあえずORBを使って特徴点を表示してみました。


OrbFeatureDetector detector(500);
// OrbDescriptorExtractor *extractor;
std::vector keypoints;
detector.detect(grayImage, keypoints);

for (int i = 0; i < keypoints.size(); i++)
{
KeyPoint p = keypoints.at(i);
cv::circle(imageMat, cv::Point(p.pt.x, p.pt.y), 1, Scalar(0, 255, 0), -1);
}


これでORB特徴点が表示されます。

今回は以上です。
.28 2013

動画像をOpenCVで解析するための準備

こんにちわ。Uedaです。

今回はタイトル通り, ios上で動画像をOpenCVで解析するための準備をしてみました。

http://reiji1020.hatenablog.com/entry/2012/11/18/165804
のサイト曰く, OpenCV2.4.2からFramework形式のものが既に準備されているので, 導入がすごく簡単になっています。

ライブラリにopencv2.frameworkを追加し, 以下のファイルUIViewControllerを実行すると, 動画像をOpenCVで画像処理・解析するためのMatの形式に変換することができます。

ヘッダファイル

@interface TestOpenCVViewController : UIViewController
{
IBOutlet UIImageView *cameraPreviewImageView;
AVCaptureSession* session;
}

@property(strong, nonatomic) AVCaptureSession *session;
@property(strong, nonatomic) UIImageView *cameraPreviewImageView;

@end


ソースファイル

using namespace cv;

@interface TestOpenCVViewController ()

@end

@implementation TestOpenCVViewController

@synthesize session;
@synthesize cameraPreviewImageView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"viewDidLoad");
// Do any additional setup after loading the view from its nib.
// ビデオキャプチャデバイスの取得
AVCaptureDevice* device;
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// オートフォーカスモードを解消
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
[device setFocusMode:AVCaptureFocusModeAutoFocus];
[device unlockForConfiguration];
}
}
// デバイス入力の取得
AVCaptureDeviceInput* deviceInput;
deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:NULL];
// ビデオデータ出力の作成
NSMutableDictionary* settings;
AVCaptureVideoDataOutput* dataOutput;
settings = [NSMutableDictionary dictionary];
[settings setObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
forKey:(id)kCVPixelBufferPixelFormatTypeKey];
dataOutput = [[AVCaptureVideoDataOutput alloc] init];
// [dataOutput autorelease];
dataOutput.videoSettings = settings;
[dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
// セッションの作成
self.session = [[AVCaptureSession alloc] init];
// 画質の制御
self.session.sessionPreset = AVCaptureSessionPreset640x480;
[self.session addInput:deviceInput];
[self.session addOutput:dataOutput];

// ステータスバーを隠す
[UIApplication sharedApplication].statusBarHidden = YES;
self.view.bounds = [UIScreen mainScreen].bounds;

// カメラの開始
[self.session startRunning];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

/***** カメラの動作 *****/
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
// キャプチャしたフレームからCGImageを作成
UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
cv::Mat imageMat = [self cvMatFromUIImage:image];

/* あとはimageMatをOpenCVで煮るなり焼くなり */

image = [self UIImageFromCVMat:imageMat];
cameraPreviewImageView.image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp];
}

// サンプルバッファのデータからCGImageRefを生成する
- (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer
{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// ピクセルバッファのベースアドレスをロックする
CVPixelBufferLockBaseAddress(imageBuffer, 0);
// Get information of the image
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
// RGBの色空間
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef newContext = CGBitmapContextCreate(baseAddress,
width,
height,
8,
bytesPerRow,
colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef cgImage = CGBitmapContextCreateImage(newContext);
CGContextRelease(newContext);
CGColorSpaceRelease(colorSpace);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
UIImage *image = [UIImage imageWithCGImage:cgImage scale:1.0 orientation:UIImageOrientationRight];
CGImageRelease(cgImage);
return image;
}

- (cv::Mat)cvMatFromUIImage:(UIImage *)image
{
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
CGFloat cols = image.size.width;
CGFloat rows = image.size.height;

cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels

CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
cols, // Width of bitmap
rows, // Height of bitmap
8, // Bits per component
cvMat.step[0], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrderDefault); // Bitmap info flags

CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
CGContextRelease(contextRef);
// CGColorSpaceRelease(colorSpace);

return cvMat;
}

- (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorSpace;

if (cvMat.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}

CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
cvMat.rows, //height
8, //bits per component
8 * cvMat.elemSize(), //bits per pixel
cvMat.step[0], //bytesPerRow
colorSpace, //colorspace
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
provider, //CGDataProviderRef
NULL, //decode
false, //should interpolate
kCGRenderingIntentDefault //intent
);


// Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return finalImage;
}


あとはMat形式にした画像をOpenCVで用意されている様々な関数を使って煮るなり, 焼くなりすればOpenCVを堪能することができます。

今回は以上です。
.27 2013

Eigenを使ってSVD(特異値分解)

こんにちわ。Uedaです。

Eigenを使ってSVD(特異値分解)をしてみました。

特異値分解 ~wiki
http://ja.wikipedia.org/wiki/特異値分解


Matrix3d P = Matrix3d::Random(3, 3);
JacobiSVD svd(P, Eigen::ComputeFullU | Eigen::ComputeFullV);
MatrixXd S = svd.singularValues();
Matrix3d U = svd.matrixU();
Matrix3d V = svd.matrixV();


コレスキー分解やLU分解も実装されているので, 便利ですね〜。

今回は以上です。
.24 2013

Eigenを使ってQR分解

こんにちわ。Uedaです。

前回, 算出した回転行列の直行行列としての性質が保証されていなかったので, QR分解します。

直行行列 ~wiki
http://ja.wikipedia.org/wiki/直交行列

QR分解は行列を直行行列と上三角行列に分解する行列です。なので, 前回算出した回転行列もどきをQR分解して, 直行行列とそうでない行列に分けて, 直行行列の方を回転行列として抽出しようということです。

回転行列もどきRをQR分解して, 直行行列を抽出します。Eigen使ったコードです。

HouseholderQR QR(R);
Matrix3d Q = QR.householderQ();


出力結果
QR分解前
0.997029, 0.077192, -0.510096
-0.015336, 1.234692, -0.650774
-0.119096, 0.023709, 0.528783

QR分解後
-0.992825, -0.018295, 0.118166
0.015271, -0.999534, -0.026448
0.118594, -0.024454, 0.992642

直行行列にできたはいいですが, 符号がバラバラになってしまってる...
 HOME 

ブログ内検索

関連リンク

製品情報

最新記事

カテゴリ

プロフィール

neoxneo



NEXT-SYSTEM iOS Developers Blog


  • UTO:
    カナダ版iPhone4Sは、マナーモードでシャッター音がならない…


  • Ehara:
    ...


  • Hayate:
    ...


  • Tasaki:
    Developer登録完了...したのはいいけど


  • Ueda:
    ...



リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。