JavaCV/OpenCVで可変角度(22°など)でいくつかの画像を回転させたいです。現時点では私が使用しています cvWarpAffine()
。
私の問題は、回転後に画像の端を失うことです。そのため、dst.imageを大きくして中心点を移動する必要があります。このページで、画像の新しいサイズを計算するための AS コードを見つけました。しかし、JavaCV/OpenCVで実現する方法がわかりません
やがて私は次のコードを持っています:
public CvMat rotateImage(int angle) {
CvPoint2D32f center = new CvPoint2D32f(input.cols() / 2.0F,
input.rows() / 2.0F);
CvMat rotMat = cvCreateMat(2, 3, CV_32F);
cv2DRotationMatrix(center, angle, 1, rotMat);
CvMat dst = cvCreateMat(input.rows(), input.cols(), input.type());
cvWarpAffine(input, dst, rotMat);
return dst;
}
誰かがアイデアを持っていますか?
ご挨拶
//アップデート
わかりません...何かが間違っています。回転した画像を計算すると、結果は正しい寸法になりますが、ほとんどが黒です (0 と 360° が機能します)。コードは次のとおりです。
public CvMat rotateImage(float angle) {
CvPoint2D32f center = new CvPoint2D32f(input.cols() / 2.0F,
input.rows() / 2.0F);
CvBox2D box = new CvBox2D(center, cvSize2D32f(input.cols() - 1,
input.rows() - 1), angle);
CvPoint2D32f points = new CvPoint2D32f(4);
cvBoxPoints(box, points);
CvMat pointMat = cvCreateMat(1, 4, CV_32FC2);
pointMat.put(0, 0, 0, points.position(0).x());
pointMat.put(0, 0, 1, points.position(0).y());
pointMat.put(0, 1, 0, points.position(1).x());
pointMat.put(0, 1, 1, points.position(1).y());
pointMat.put(0, 2, 0, points.position(2).x());
pointMat.put(0, 2, 1, points.position(2).y());
pointMat.put(0, 3, 0, points.position(3).x());
pointMat.put(0, 3, 1, points.position(3).y());
CvRect boundingRect = cvBoundingRect(pointMat, 0);
CvMat dst = cvCreateMat(boundingRect.height(), boundingRect.width(),
input.type());
CvPoint2D32f centerDst = new CvPoint2D32f(center.x()
+ (dst.cols() / 2.0F), center.y() + (dst.rows() / 2.0F));
CvMat rotMat = cvCreateMat(2, 3, CV_32F);
cv2DRotationMatrix(centerDst, angle, 1, rotMat);
CvMat trans = cvCreateMat(3, 3, CV_32F);
cvZero(trans);
trans.put(0, 2, dst.cols() / 2.0F);
trans.put(1, 2, dst.rows() / 2.0F);
trans.put(0, 0, 1);
trans.put(1, 1, 1);
trans.put(2, 2, 1);
CvMat newRot = cvCreateMat(3, 3, CV_32F);
cvZero(newRot);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
newRot.put(i, j, rotMat.get(i, j));
}
}
newRot.put(2, 2, 1);
cvMul(trans, newRot, newRot, 1);
cvWarpPerspective(input, dst, newRot);
// cvWarpAffine(input, dst, dstRotMat);
return dst;
}
次のrotMat
ようになります。
[ 0.9396926, 0.34202015, -311.1334
-0.34202015, 0.9396926, 601.47485 ]
(trans
組織の画像のサイズは 1428x928px です):
[ 1.0, 0.0, 836.0
0.0, 1.0, 699.0
0.0, 0.0, 1.0 ]
そしてそのnewRot
[ 0.9396926, 0.0, -260107.52
-0.0, 0.9396926, 420430.94
0.0, 0.0, 1.0 ]
私は間違いを見つけることができません
//更新 2
public CvMat rotateImage(float angle) {
CvPoint2D32f center = new CvPoint2D32f(input.cols() / 2.0F,
input.rows() / 2.0F);
CvBox2D box = new CvBox2D(center, cvSize2D32f(input.cols() - 1,
input.rows() - 1), angle);
CvPoint2D32f points = new CvPoint2D32f(4);
cvBoxPoints(box, points);
CvMat pointMat = cvCreateMat(1, 4, CV_32FC2);
pointMat.put(0, 0, 0, points.position(0).x());
pointMat.put(0, 0, 1, points.position(0).y());
pointMat.put(0, 1, 0, points.position(1).x());
pointMat.put(0, 1, 1, points.position(1).y());
pointMat.put(0, 2, 0, points.position(2).x());
pointMat.put(0, 2, 1, points.position(2).y());
pointMat.put(0, 3, 0, points.position(3).x());
pointMat.put(0, 3, 1, points.position(3).y());
CvRect boundingRect = cvBoundingRect(pointMat, 0);
CvMat dst = cvCreateMat(boundingRect.height(), boundingRect.width(),
input.type());
// CvPoint2D32f centerDst = new CvPoint2D32f(((dst.cols()-input.cols()
// )/ 2.0F),(( dst.rows()-input.rows()) / 2.0F));
CvMat rotMat = cvCreateMat(2, 3, CV_32F);
cv2DRotationMatrix(center, angle, 1, rotMat);
CvMat trans = cvCreateMat(3, 3, CV_32F);
cvZero(trans);
trans.put(0, 2, (dst.cols() - input.cols()) / 2.0F);
trans.put(1, 2, (dst.rows() - input.rows()) / 2.0F);
trans.put(0, 0, 1);
trans.put(1, 1, 1);
trans.put(2, 2, 1);
CvMat newRot = cvCreateMat(3, 3, CV_32F);
cvZero(newRot);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
newRot.put(i, j, rotMat.get(i, j));
}
}
newRot.put(2, 2, 1);
cvMul(trans, newRot, newRot, 1);
cvWarpPerspective(input, dst, newRot);
// cvWarpAffine(input, dst, rotMat);
System.out.println(rotMat);
System.out.println(trans);
System.out.println(newRot);
return dst;
1 度では、行列は次のようになります。
rotMat
:
[ 0.9998477, 0.017452406, -8.338219
-0.017452406, 0.9998477, 12.534734 ]
trans
[ 1.0, 0.0, -8.0
0.0, 1.0, -12.0
0.0, 0.0, 1.0 ]
newRot
[ 0.9998477, 0.0, 66.70575
-0.0, 0.9998477, -150.41681
0.0, 0.0, 1.0 ]
最後の
Hammer からの命令の作業 JavaCode:
public CvMat rotateImage(float angle) {
CvPoint2D32f center = new CvPoint2D32f(input.cols() / 2.0F,
input.rows() / 2.0F);
CvBox2D box = new CvBox2D(center, cvSize2D32f(input.cols() - 1,
input.rows() - 1), angle);
CvPoint2D32f points = new CvPoint2D32f(4);
cvBoxPoints(box, points);
CvMat pointMat = cvCreateMat(1, 4, CV_32FC2);
pointMat.put(0, 0, 0, points.position(0).x());
pointMat.put(0, 0, 1, points.position(0).y());
pointMat.put(0, 1, 0, points.position(1).x());
pointMat.put(0, 1, 1, points.position(1).y());
pointMat.put(0, 2, 0, points.position(2).x());
pointMat.put(0, 2, 1, points.position(2).y());
pointMat.put(0, 3, 0, points.position(3).x());
pointMat.put(0, 3, 1, points.position(3).y());
CvRect boundingRect = cvBoundingRect(pointMat, 0);
CvMat dst = cvCreateMat(boundingRect.height(), boundingRect.width(),
input.type());
CvMat rotMat = cvCreateMat(2, 3, CV_32FC1);
cv2DRotationMatrix(center, angle, 1, rotMat);
double y_1 = ((boundingRect.width() - input.cols()) / 2.0F)
+ rotMat.get(0, 2);
double y_2 = ((boundingRect.height() - input.rows()) / 2.0F + rotMat
.get(1, 2));
rotMat.put(0, 2, y_1);
rotMat.put(1, 2, y_2);
cvWarpAffine(input, dst, rotMat);
return dst;
}