映像信号が反転していたり
端末が横向きだったり
ライブラリによって左下座標系だったり右上座標系だったり
範囲が0〜1に正規化されていたり
ウザいんであっちの座標系からこっちの座標系の変換クラスを用意しました
いまだにObjCしか知らなくてスイマセン
Coordinateクラス
Coordinate.h
typedef NS_ENUM(NSInteger, CoordinateSystem)
{
CoordinateSystemLeftDown,
CoordinateSystemLeftUp,
CoordinateSystemRightDown,
CoordinateSystemRightUp,
};
@interface Coordinate : NSObject
+(CGRect)changeCoordinateRect:(CGRect)rect
from:(CoordinateSystem)fromCoordinate orientation:(UIInterfaceOrientation)fromOrientation size:(CGSize)fromSize isNormalize:(BOOL)fromNormalize
to:(CoordinateSystem)toCoordinate orientation:(UIInterfaceOrientation)toOrientation size:(CGSize)toSize isNormalize:(BOOL)toNormalize;
+(CGPoint)changeCoordinatePoint:(CGPoint)point
from:(CoordinateSystem)fromCoordinate orientation:(UIInterfaceOrientation)fromOrientation size:(CGSize)fromSize isNormalize:(BOOL)fromNomalize
to:(CoordinateSystem)toCoordinate orientation:(UIInterfaceOrientation)toOrientation size:(CGSize)toSize isNormalize:(BOOL)toNormalize;
@end
Coordinate.m
@implementation Coordinate
+(CGPoint)changeCoordinatePoint:(CGPoint)point
from:(CoordinateSystem)fromCoordinate orientation:(UIInterfaceOrientation)fromOrientation size:(CGSize)fromSize isNormalize:(BOOL)fromNomalize
to:(CoordinateSystem)toCoordinate orientation:(UIInterfaceOrientation)toOrientation size:(CGSize)toSize isNormalize:(BOOL)toNormalize{
float x = point.x;
float y = point.y;
if(!fromNomalize){
x = x / fromSize.width;
y = y / fromSize.height;
}
CGAffineTransform t = [Coordinate transformFrom:fromCoordinate orientation:fromOrientation to:toCoordinate orientation:toOrientation];
CGPoint last = CGPointApplyAffineTransform((CGPoint){x, y}, t);
if(!toNormalize){
last.x = last.x * toSize.width;
last.y = last.y * toSize.height;
}
return last;
}
+(CGRect)changeCoordinateRect:(CGRect)rect
from:(CoordinateSystem)fromCoordinate orientation:(UIInterfaceOrientation)fromOrientation size:(CGSize)fromSize isNormalize:(BOOL)fromNormalize
to:(CoordinateSystem)toCoordinate orientation:(UIInterfaceOrientation)toOrientation size:(CGSize)toSize isNormalize:(BOOL)toNormalize{
float x = rect.origin.x;
float y = rect.origin.y;
float w = rect.size.width;
float h = rect.size.height;
if(!fromNormalize){
x = x / fromSize.width;
y = y / fromSize.height;
w = w / fromSize.width;
h = h / fromSize.height;
}
CGAffineTransform t = [Coordinate transformFrom:fromCoordinate orientation:fromOrientation to:toCoordinate orientation:toOrientation];
CGRect last = CGRectApplyAffineTransform((CGRect){x, y, w, h}, t);
if(!toNormalize){
last = (CGRect){
last.origin.x * toSize.width,
last.origin.y * toSize.height,
last.size.width * toSize.width,
last.size.height * toSize.height,
};
}
return last;
}
+(CGAffineTransform)transformFrom:(CoordinateSystem)fromCoordinate orientation:(UIInterfaceOrientation)fromOrientation
to:(CoordinateSystem)toCoordinate orientation:(UIInterfaceOrientation)toOrientation{
CGAffineTransform t = CGAffineTransformIdentity;
//上下反転
if(
(
//端末の傾きについての条件
fromOrientation == toOrientation
&&
//座標系の条件
((fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightUp)
)
)
||
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationLandscapeLeft)
)
&&
//座標系の条件
(
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemLeftDown)
)
)
){
//上下反転
t = [Utils concats:@[
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeScale(1, -1)],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeTranslation(0, 1)],
]];
}
//左右反転
else if(
(
//端末の傾きについての条件
fromOrientation == toOrientation
&&
//座標系の条件
(
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightUp)
)
)
||
(
(
//端末の傾きについての条件
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationLandscapeLeft)
)
&&
(
//座標系の条件
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightUp)
)
)
){
//左右反転
t = [Utils concats:@[
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeScale(-1, 1)],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeTranslation(1, 0)],
]];
}
//縦横入れ替え
else if(
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortrait)
)
&&
(
//座標系の条件
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemLeftDown)
)
)
||
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
)
&&
(
//座標系の条件
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightUp)
)
)
){
//縦横入れ替え
//xとyをwidthとheight入れ替える
t = CGAffineTransformMake(0, 1, 1, 0, 0, 0);
}
//上下反転・左右反転
else if(
(
//端末の傾きについての条件
(fromOrientation == toOrientation)
&&
//座標系の条件
(
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemLeftUp)
)
)
||
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationLandscapeLeft)
)
&&
//座標系の条件
(fromCoordinate == toCoordinate)
)
){
//上下反転・左右反転
t = [Utils concats:@[
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeScale(-1, -1)],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeTranslation(1, 1)],
]];
}
//上下反転・縦横入れ替え
else if(
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortrait)
)
&&
//座標系の条件
((fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemLeftUp)
)
)
||
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
)
&&
//座標系の条件
(
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightDown)
)
)
){
//上下反転・縦横入れ替え
t = [Utils concats:@[
//xとyをwidthとheight入れ替える
[NSValue valueWithCGAffineTransform:CGAffineTransformMake(0, 1, 1, 0, 0, 0)],
//上下反転
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeScale(1, -1)],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeTranslation(0, 1.0)],
]];
}
//左右反転・縦横入れ替え
else if(
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortrait))
&&
//座標系の条件
((fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightDown)
)
)
||
(
//端末の傾きについての条件
((fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
)
&&
//座標系の条件
((fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemLeftUp)
)
)
){
//左右反転・縦横入れ替え
// t = CGAffineTransformMake(0, -1, 1, 0, 0, 1);
t = [Utils concats:@[
//xとyをwidthとheight入れ替える
[NSValue valueWithCGAffineTransform:CGAffineTransformMake(0, 1, 1, 0, 0, 0)],
//左右反転
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeScale(-1, 1)],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeTranslation(1, 0)],
]];
}
//上下反転・左右反転・縦横入れ替え
else if(
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortrait)
)
&&
//座標系の条件
(
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemLeftDown)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemRightUp)
)
)
||
(
//端末の傾きについての条件
(
(fromOrientation == UIInterfaceOrientationPortrait && toOrientation == UIInterfaceOrientationLandscapeRight)
||
(fromOrientation == UIInterfaceOrientationLandscapeLeft && toOrientation == UIInterfaceOrientationPortrait)
||
(fromOrientation == UIInterfaceOrientationPortraitUpsideDown && toOrientation == UIInterfaceOrientationLandscapeLeft)
||
(fromOrientation == UIInterfaceOrientationLandscapeRight && toOrientation == UIInterfaceOrientationPortraitUpsideDown)
)
&&
//座標系の条件
(
(fromCoordinate == CoordinateSystemLeftUp && toCoordinate == CoordinateSystemRightUp)
||
(fromCoordinate == CoordinateSystemLeftDown && toCoordinate == CoordinateSystemLeftUp)
||
(fromCoordinate == CoordinateSystemRightUp && toCoordinate == CoordinateSystemRightDown)
||
(fromCoordinate == CoordinateSystemRightDown && toCoordinate == CoordinateSystemLeftDown)
)
)
){
//上下反転・左右反転・縦横入れ替え
t = [Utils concats:@[
//xとyをwidthとheight入れ替える
[NSValue valueWithCGAffineTransform:CGAffineTransformMake(0, 1, 1, 0, 0, 0)],
//上下左右反転
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeScale(-1, -1)],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeTranslation(1, 1)],
]];
}
return t;
}
+(CGAffineTransform)concats:(NSArray*)affineTransforms{
CGAffineTransform t = CGAffineTransformIdentity;
for (id obj in affineTransforms) {
CGAffineTransform a = [obj CGAffineTransformValue];
t = CGAffineTransformConcat(t, a);
}
return t;
}
@end
使い方
/*
ライブラリSomeLib1で顔を検出して、別のライブラリSomeLibe2にその情報を渡したいけど座標系とかが違う場合
imageの方向 : 縦向き (UIDeviceOrientationPortrait)
SomeLib1の座標系 : 左下座標系 (CoordinateSystemLeftDown)
SomeLib1の向き : 縦向き (UIDeviceOrientationPortrait)
SomeLib1の範囲 : 0〜1に正規化
SomeLib2の座標系 : 右上座標系 (CoordinateSystemRightUp)
SomeLib2の向き : 横向き (UIDeviceOrientationLandscapeLeft)
SomeLib2の範囲 : 画像サイズ
*/
CGRect r = [SomeLib1 getFaceWithUIImage:image];
//座標系をSomeLib1のものからSomeLib2のものへ変換
CGRect r2 = [Coordinate changeCoordinateRect:r //変換前のCGRect
//変換前の情報
from:CoordinateSystemLeftDown
orientation:UIDeviceOrientationPortrait
size:image.size
isNormalize:YES
//変換後の情報
to:CoordinateSystemRightUp
orientation:UIDeviceOrientationLandscapeLeft
size:(CGSize){image.size.height, image.size.width}
isNormalize:NO];
//SomeLib2に渡す
[SomeLib2 setFaceRect:r2];