先看效果圖
原圖
拼接后的效果圖
下面開始介紹拼接圖片過(guò)程
請(qǐng)看項(xiàng)目目錄
在Github
上面搜索CVWrapper
句葵,選擇Objective-C
部分检盼,將上圖中的文件導(dǎo)入到項(xiàng)目中瓜饥。ImageUnti
是我另外添加的裁剪圖片的工具類诊笤,你們可以在我之前的文章中找一下源代碼嫡锌。
由于opencv
庫(kù)太大怒医,在github
上面下載的項(xiàng)目中炉抒,里面會(huì)沒(méi)有相應(yīng)的framework
文件,這時(shí)候稚叹,可以去github
或百度上面另外下載焰薄。
編譯一下項(xiàng)目,如果沒(méi)有出錯(cuò)扒袖,就可以繼續(xù)使用了塞茅。
使用過(guò)程
請(qǐng)看代碼
#import "ViewController.h"
#import "CVWrapper.h"
#import "ImageUtil.h"
@interface ViewController ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (nonatomic,strong) UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *indictor;
@end
@implementation ViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.indictor.center = self.view.center;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.imageView.contentMode = UIViewContentModeScaleToFill;
[self createFullShotImages];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark 異步線程 拼接全景圖片
- (void)createFullShotImages
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.indictor startAnimating];
CGSize size = CGSizeMake(720, 960);
NSMutableArray *images = [NSMutableArray array];
for (int i = 0; i<7; i++)
{
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]];
NSAssert(image != nil, @"image 數(shù)據(jù)不能為空");
[images addObject:[ImageUtil resizeImageWithImage:image targetSize:CGSizeMake(640, 360)]];
}
//TODO:在這里傳入需要拼接的圖片數(shù)組,返回拼接后的圖片
UIImage *fullShotImage = [CVWrapper processWithArray:images];
//回到主線程中顯示拼接后的image
dispatch_async(dispatch_get_main_queue(), ^{
UIImageView *midImageView = [[UIImageView alloc]initWithImage:fullShotImage];
self.imageView = midImageView;
[self.scrollView addSubview:self.imageView];
//利用scrollView控制全景圖片的縮放
self.scrollView.backgroundColor = [UIColor darkGrayColor];
self.scrollView.contentSize = self.imageView.bounds.size;
self.scrollView.maximumZoomScale = 4.0;
self.scrollView.minimumZoomScale = 0.5;
self.scrollView.delegate = self;
CGFloat pointX = -(self.scrollView.bounds.size.width - self.imageView.bounds.size.width)/2.0;
CGFloat pointY = -(self.scrollView.bounds.size.height - self.imageView.bounds.size.height)/2.0;
self.scrollView.contentOffset = CGPointMake(pointX, pointY);
[self.indictor stopAnimating];
self.indictor.hidesWhenStopped = YES;
});
});
}
- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
主要代碼使用起來(lái)很簡(jiǎn)單季率,但是還有幾點(diǎn)需要注意
- 每?jī)蓚€(gè)相鄰的拼接圖片之間需要有重疊的部分
- 所有需要拼接的圖片需要處于同一水平線上野瘦,不然可能會(huì)有拼接失敗或圖片混亂的情況
libjpeg.a
文件是輔助opencv
使用的,這個(gè)也不可缺少飒泻。
至于制作全景相機(jī)的思路鞭光,我們可以使用自定義相機(jī),利用重力感應(yīng)控制好輸出圖片的水平位置泞遗,然后拍攝和拼接圖片惰许。我的思路不一定是最簡(jiǎn)單和正確的,還請(qǐng)各位多多指教史辙。
要源碼的人太多了汹买,這里就把完整版的項(xiàng)目上傳一下,地址完整版項(xiàng)目+OpenCV.Framework聊倔,密碼:xr0u晦毙。代碼在分享的過(guò)程中才能更加完善,謝謝各位的指導(dǎo)耙蔑,喜歡的小伙伴可以給一個(gè)小心心(笑哭),打賞就不用了见妒。
補(bǔ)充
當(dāng)單個(gè)圖片分辨率過(guò)大時(shí),在合成的過(guò)程中會(huì)因?yàn)閿?shù)據(jù)越界出現(xiàn)下面的錯(cuò)誤提示
OpenCV Error: Assertion failed ((globalDescIdx>=0) && (globalDescIdx < size())) in getLocalIdx, file /Volumes/build-storage/build/2_4_iOS-mac/opencv/modules/features2d/src/matchers.cpp, line 163
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Volumes/build-storage/build/2_4_iOS-mac/opencv/modules/features2d/src/matchers.cpp:163: error: (-215) (globalDescIdx>=0) && (globalDescIdx < size()) in function getLocalIdx
這時(shí)可以降低一下圖片的分辨率甸陌,使用ImageUtil
這個(gè)類中的resizeImageWithImage: targetSize:
方法即可须揣。