2

I'd like to take an affine matrix that I have from OpenCV:

Mat T = getAffineTransform(src_pt, dst_pt);

and then convert it into a CGAffineTransform for use in Core Graphics/Objective-C/iOS. (CGAffineTransform docs)

I've tried:

CGAffineTransform t = CGAffineTransformIdentity;
t.a = T.at<float>(0,0);
t.b = T.at<float>(0,1);
t.c = T.at<float>(1,0);
t.d = T.at<float>(1,1);
t.tx = T.at<float>(0,2);
t.ty = T.at<float>(1,2);

This works fine for x and y translations, but NOT if there is any rotation in the matrix. Something seems to be missing since the resulting image seems to be skewed strangely. I've tried multiplying .b and .c by -1 and switching .b and .c, but neither of those seemed to work. The image still appeared incorrectly skewed.

Edit: I should mention that it's almost rotated correctly. When I switch b and c it's at least rotated in the right direction. It just seems a bit off, as in rotated a little too far.

taber
  • 3,166
  • 4
  • 46
  • 72
  • I'm surprised switching `b` and `c` didn't work, since that would result in the correct rotation. Your posted code currently constructs an incorrect rotation. – Aurelius Jan 17 '13 at 22:48
  • Yeah I tried `t.b = T.at(1,0)` and `t.c = T.at(0,1)` but no luck. I think it may have something to do with the origin. – taber Jan 18 '13 at 00:01

1 Answers1

2

Your problem is that opencv is row major and CGAffineTransform is column major you want

t.a = T.at<float>(0,0);
t.b = T.at<float>(1,0);
t.c = T.at<float>(0,1);
t.d = T.at<float>(1,1);

you can tell because in the documentation CGAffineTransform takes the form

[a  b  0
 c  d  0
 tx ty 1]

note that tx and ty are in the bottom row. In standard row major matrices the translation components go in the rightmost column

[a c tx
 b d ty
 0 0 1]

If the problem persists after making this change (which your question suggests you have already tried) then you need to post more information. As you suggest the problem could be in the origin of your coordinate system but without any information about your origin nobody will be able to help you.

Hammer
  • 10,109
  • 1
  • 36
  • 52
  • Alright thanks, I'll try to update in further detail with images, etc. – taber Jan 18 '13 at 00:17
  • Got it! It was a combination of swapping b and c, needing to set the layer's anchorPoint to 0,0 and then translating by -1/2 the image width, -1/2 the image height. Thanks. – taber Jan 18 '13 at 04:53
  • @taber: The first part—b and c being swapped—is why you were getting skew behavior. You can see this for yourself by manually swapping the numbers around in [my affine transform test app](https://github.com/boredzo/AffineTransformTest). – Peter Hosey Jan 18 '13 at 07:27