Soru OpenCV: IplImage nasıl döndürülür?


Bir görüntüyü 1-5 derece gibi çok küçük bir açıyla döndürmem gerekiyor. does OpenCV Bunu yapmanın basit bir yolunu mu? Dokümanları okumaktan şunu söyleyebilirim getAffineTransform () dahil olmalı, ancak böyle bir şey yapmanın doğrudan bir örneği yoktur:

IplImage *rotateImage( IplImage *source, double angle);

25
2018-02-18 15:22


Menşei




Cevaplar:


OpenCV> 2.0 kullanıyorsanız, o kadar kolay

using namespace cv;

Mat rotateImage(const Mat& source, double angle)
{
    Point2f src_center(source.cols/2.0F, source.rows/2.0F);
    Mat rot_mat = getRotationMatrix2D(src_center, angle, 1.0);
    Mat dst;
    warpAffine(source, dst, rot_mat, source.size());
    return dst;
}

Not: açı radyan değil derecedir.

Daha fazla ayrıntı için C ++ arayüzü belgelerine bakın ve ihtiyacınız olan şekilde uyarlayın:


42
2018-02-20 00:04





Düzenleme: Aşağı seçmen için: Lütfen denenmiş ve test edilmiş bir kodun reddedilme nedenini açıklayın.

#include "cv.h"
#include "highgui.h"
#include "math.h"
int main( int argc, char** argv )
{
    IplImage* src = cvLoadImage("lena.jpg", 1);    
    IplImage* dst = cvCloneImage( src );

    int delta = 1;
    int angle = 0;
    int opt = 1;   // 1: rotate & zoom
               // 0:  rotate only
    double factor;
    cvNamedWindow("src", 1);
    cvShowImage("src", src);

    for(;;)
    {
    float m[6];
    CvMat M = cvMat(2, 3, CV_32F, m);
    int w = src->width;
    int h = src->height;

    if(opt)  
        factor = (cos(angle*CV_PI/180.) + 1.05) * 2;
    else 
        factor = 1;
    m[0] = (float)(factor*cos(-angle*2*CV_PI/180.));
    m[1] = (float)(factor*sin(-angle*2*CV_PI/180.));
    m[3] = -m[1];
    m[4] = m[0];
    m[2] = w*0.5f;  
    m[5] = h*0.5f;  

    cvGetQuadrangleSubPix( src, dst, &M);
    cvNamedWindow("dst", 1);
    cvShowImage("dst", dst);
    if( cvWaitKey(1) == 27 )
        break;
    angle =(int)(angle + delta) % 360;
    }     
    return 0;
}

GÜNCELLEŞTİRME: Warpaffine kullanarak rotasyon için aşağıdaki koda bakın https://code.google.com/p/opencvjp-sample/source/browse/trunk/cpp/affine2_cpp.cpp?r=48

#include <cv.h>
#include <highgui.h>

using namespace cv;

int
main(int argc, char **argv)
{
  // (1)load a specified file as a 3-channel color image,
  //    set its ROI, and allocate a destination image
  const string imagename = argc > 1 ? argv[1] : "../image/building.png";
  Mat src_img = imread(imagename);
  if(!src_img.data)
    return -1;
  Mat dst_img = src_img.clone();

  // (2)set ROI
  Rect roi_rect(cvRound(src_img.cols*0.25), cvRound(src_img.rows*0.25), cvRound(src_img.cols*0.5), cvRound(src_img.rows*0.5));
  Mat src_roi(src_img, roi_rect);
  Mat dst_roi(dst_img, roi_rect);

  // (2)With specified three parameters (angle, rotation center, scale)
  //    calculate an affine transformation matrix by cv2DRotationMatrix
  double angle = -45.0, scale = 1.0;
  Point2d center(src_roi.cols*0.5, src_roi.rows*0.5);
  const Mat affine_matrix = getRotationMatrix2D( center, angle, scale );

  // (3)rotate the image by warpAffine taking the affine matrix
  warpAffine(src_roi, dst_roi, affine_matrix, dst_roi.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar::all(255));

  // (4)show source and destination images with a rectangle indicating ROI
  rectangle(src_img, roi_rect.tl(), roi_rect.br(), Scalar(255,0,255), 2);

  namedWindow("src", CV_WINDOW_AUTOSIZE);
  namedWindow("dst", CV_WINDOW_AUTOSIZE);
  imshow("src", src_img);
  imshow("dst", dst_img);
  waitKey(0);

  return 0;
}

5
2017-08-16 18:10





Cevabımı benzer bir soruna bakın:

Bir resmi C / C ++ ile döndürme

Esas olarak, kullanım cvWarpAffine - Önceki cevabımda 2x3 dönüştürme matrisini açıdan nasıl alacağımı anlattım.


4
2018-02-18 15:33





OpenCV 2.4 ve üzeri için tam yanıt güncelleme

// ROTATE p by R
/**
 * Rotate p according to rotation matrix (from getRotationMatrix2D()) R
 * @param R     Rotation matrix from getRotationMatrix2D()
 * @param p     Point2f to rotate
 * @return      Returns rotated coordinates in a Point2f
 */
Point2f rotPoint(const Mat &R, const Point2f &p)
{
    Point2f rp;
    rp.x = (float)(R.at<double>(0,0)*p.x + R.at<double>(0,1)*p.y + R.at<double>(0,2));
    rp.y = (float)(R.at<double>(1,0)*p.x + R.at<double>(1,1)*p.y + R.at<double>(1,2));
    return rp;
}

//COMPUTE THE SIZE NEEDED TO LOSSLESSLY STORE A ROTATED IMAGE
/**
 * Return the size needed to contain bounding box bb when rotated by R
 * @param R     Rotation matrix from getRotationMatrix2D()
 * @param bb    bounding box rectangle to be rotated by R
 * @return      Size of image(width,height) that will compleley contain bb when rotated by R
 */
Size rotatedImageBB(const Mat &R, const Rect &bb)
{
    //Rotate the rectangle coordinates
    vector<Point2f> rp;
    rp.push_back(rotPoint(R,Point2f(bb.x,bb.y)));
    rp.push_back(rotPoint(R,Point2f(bb.x + bb.width,bb.y)));
    rp.push_back(rotPoint(R,Point2f(bb.x + bb.width,bb.y+bb.height)));
    rp.push_back(rotPoint(R,Point2f(bb.x,bb.y+bb.height)));
    //Find float bounding box r
    float x = rp[0].x;
    float y = rp[0].y;
    float left = x, right = x, up = y, down = y;
    for(int i = 1; i<4; ++i)
    {
        x = rp[i].x;
        y = rp[i].y;
        if(left > x) left = x;
        if(right < x) right = x;
        if(up > y) up = y;
        if(down < y) down = y;
    }
    int w = (int)(right - left + 0.5);
    int h = (int)(down - up + 0.5);
    return Size(w,h);
}

/**
 * Rotate region "fromroi" in image "fromI" a total of "angle" degrees and put it in "toI" if toI exists.
 * If toI doesn't exist, create it such that it will hold the entire rotated region. Return toI, rotated imge
 *   This will put the rotated fromroi piece of fromI into the toI image
 *
 * @param fromI     Input image to be rotated
 * @param toI       Output image if provided, (else if &toI = 0, it will create a Mat fill it with the rotated image roi, and return it).
 * @param fromroi   roi region in fromI to be rotated.
 * @param angle     Angle in degrees to rotate
 * @return          Rotated image (you can ignore if you passed in toI
 */
Mat rotateImage(const Mat &fromI, Mat *toI, const Rect &fromroi, double angle)
{
    //CHECK STUFF
    // you should protect against bad parameters here ... omitted ...

    //MAKE OR GET THE "toI" MATRIX
    Point2f cx((float)fromroi.x + (float)fromroi.width/2.0,fromroi.y +
               (float)fromroi.height/2.0);
    Mat R = getRotationMatrix2D(cx,angle,1);
    Mat rotI;
    if(toI)
        rotI = *toI;
    else
    {
        Size rs = rotatedImageBB(R, fromroi);
        rotI.create(rs,fromI.type());
    }

    //ADJUST FOR SHIFTS
    double wdiff = (double)((cx.x - rotI.cols/2.0));
    double hdiff = (double)((cx.y - rotI.rows/2.0));
    R.at<double>(0,2) -= wdiff; //Adjust the rotation point to the middle of the dst image
    R.at<double>(1,2) -= hdiff;

    //ROTATE
    warpAffine(fromI, rotI, R, rotI.size(), INTER_CUBIC, BORDER_CONSTANT, Scalar::all(0)); 

    //& OUT
    return(rotI);
}

3
2018-04-29 18:02





IplImage* rotate(double angle, float centreX, float centreY, IplImage* src, bool crop)
{
    int w=src->width;
    int h=src->height;

        CvPoint2D32f centre;
        centre.x = centreX;
        centre.y = centreY;

        CvMat* warp_mat = cvCreateMat(2, 3, CV_32FC1);

        cv2DRotationMatrix(centre, angle, 1.0, warp_mat);

        double m11= cvmGet(warp_mat,0,0);
        double m12= cvmGet(warp_mat,0,1);
        double m13= cvmGet(warp_mat,0,2);
        double m21= cvmGet(warp_mat,1,0);
        double m22= cvmGet(warp_mat,1,1);
        double m23= cvmGet(warp_mat,1,2);
        double m31= 0;
        double m32= 0;
        double m33= 1;
        double x=0;
        double y=0;
        double u0= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);
        double v0= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);
        x=w;
        y=0;
        double u1= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);
        double v1= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);
        x=0;
        y=h;
        double u2= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);
        double v2= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);
        x=w;
        y=h;
        double u3= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);
        double v3= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

        int left= MAX(MAX(u0,u2),0);
        int right= MIN(MIN(u1,u3),w);
        int top= MAX(MAX(v0,v1),0);
        int bottom= MIN(MIN(v2,v3),h);

        ASSERT(left<right&&top<bottom); // throw message?
        if (left<right&&top<bottom)
        {
            IplImage* dst= cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, src->nChannels);
            cvWarpAffine(src, dst, warp_mat/*, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0)*/);

            if (crop) // crop and resize to initial size
            {
                IplImage* dst_crop= cvCreateImage(cvSize(right-left, bottom-top), IPL_DEPTH_8U, src->nChannels);
                cvSetImageROI(dst,cvRect(left,top,right-left,bottom-top));
                cvCopy(dst,dst_crop);
                cvReleaseImage(&dst);
                cvReleaseMat(&warp_mat);
                //ver1 
                //return dst_crop;
                // ver2 resize
                IplImage* out= cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, src->nChannels);
                cvResize(dst_crop,out);
                cvReleaseImage(&dst_crop);
                return out;
            }
            else
            {
                /*cvLine( dst, cvPoint(left,top),cvPoint(left, bottom), cvScalar(0, 0, 255, 0) ,1,CV_AA);
                cvLine( dst, cvPoint(right,top),cvPoint(right, bottom), cvScalar(0, 0, 255, 0) ,1,CV_AA);
                cvLine( dst, cvPoint(left,top),cvPoint(right, top), cvScalar(0, 0, 255, 0) ,1,CV_AA);
                cvLine( dst, cvPoint(left,bottom),cvPoint(right, bottom), cvScalar(0, 0, 255, 0) ,1,CV_AA);*/
                cvReleaseMat(&warp_mat);
                return dst;
            }
        }
        else
        {
            return NULL;  //assert?
        }
}

-1
2017-08-13 09:21



Aşağı çekmek için bir sebep verin! 'Cevabın kullanışlı olmadığını söylüyor'. Neden olmasın? - mehfoos yacoob