利用OpenCV实现图像的仿射变换

来源:互联网 发布:c语言源文件名命名规则 编辑:程序博客网 时间:2024/06/08 18:20
利用OpenCV实现图像的仿射变换
仿射变换可以形象的表示成如下形式:一个平面内任意的平行四边形ABCD可以被仿射变换映射为另一个平行四边形A'B'C'D',如果四边形的面积不等于0,仿射变换就被这两个平行四边形(其中的三个顶点)唯一的定义,这里注意确定一个平行四边形只需要三个顶点。我们可以把仿射变换想象成把一幅图像画到一个胶板上,在胶板的角上推或拉以得到不同的平行四边形。
下面的程序实现了对图像的仿射变换,还包括图像旋转、缩放这两个重要的子集。

    #include <cv.h>
    #include <highgui.h>
    #include <stdio.h>
    #include <iostream.h>
    int main( int argc, char** argv )
    {
    CvPoint2D32f srcTri[3],dstTri[3];
    CvMat* rot_mat = cvCreateMat( 2, 3, CV_32FC1 );
    CvMat* warp_mat = cvCreateMat( 2, 3, CV_32FC1 );
    IplImage *src, *dst, *srcBak, *dstBak;
    int TLx = 0, TLy = 0, TRx = 0, TRy = 0, DLx = 0, DLy = 0;
    double angle = 40, scale = 0.8;
    float delta = 0.01;
    int PressKey;
    char name[1][80];
    if(!(src=cvLoadImage("C:/Users/jinxing/Desktop/Tests/test/Debug/lena.bmp",1)) )
    {
    printf("Input Error\n");
    return -1;
    }
    srcTri[0].x = 0;// Top left
    srcTri[0].y = 0;
    srcTri[1].x = src->width-1;//Top right
    srcTri[1].y = 0;
    srcTri[2].x = 0;//Down left
    srcTri[2].y = src->height-1;
    dst = cvCloneImage(src);
    srcBak = cvCloneImage(src);
    cvCopy(src,srcBak);
    dst->origin = src->origin;
    cvZero(dst);
    cvNamedWindow( "AffineTransform", 1 );
    CvFont font = cvFont( 1, 1 );
    while(1)
    {
    dstTri[0].x = srcBak->width*delta*(TLx%101);
    dstTri[0].y = srcBak->height*delta*(TLy%101);
    dstTri[1].x = srcBak->width-1 - srcBak->width*delta*(TRx%101);
    dstTri[1].y = srcBak->height*delta*(TRy%101);
    dstTri[2].x = srcBak->width*delta*(DLx%101);
    dstTri[2].y = srcBak->height-1 - srcBak->height*delta*(DLy%101);
    cvGetAffineTransform(srcTri,dstTri,warp_mat);
    cvWarpAffine(srcBak,dst,warp_mat);
    cvCopy(dst,src);
    CvPoint2D32f center = cvPoint2D32f(src->width/2,src->height/2);
    cv2DRotationMatrix(center,angle,scale,rot_mat);
    cvWarpAffine(src,dst,rot_mat);
    dstBak = cvCloneImage(dst);
    cvCopy(dst,dstBak);
    //--------------------------字符显示--------------------------------//
    char buf[8];
    char dspStr1[32] = {'|'};
    char dspStr2[32] = {'|'};
    char dspStr3[32] = {'|'};
    char dspStr4[32] = {'|'};
    memset(buf,'/0',sizeof(buf));
    strcat(dspStr1,itoa(TLx%101,buf,10));
    strcat(dspStr1,",");
    strcat(dspStr1,itoa(TLy%101,buf,10));
    strcat(dspStr1,"|TL");
    strcat(dspStr2,"angle=");
    strcat(dspStr2,itoa(int(angle),buf,10));
    strcat(dspStr2,",scale=");
    strcat(dspStr2,itoa(int(scale*100),buf,10));
    strcat(dspStr2,"%|");
    strcat(dspStr3,itoa(TRx%101,buf,10));
    strcat(dspStr3,",");
    strcat(dspStr3,itoa(TRy%101,buf,10));
    strcat(dspStr3,"|TR");
    strcat(dspStr4,itoa(DLx%101,buf,10));
    strcat(dspStr4,",");
    strcat(dspStr4,itoa(DLy%101,buf,10));
    strcat(dspStr4,"|DL");
    cvPutText(dst,dspStr1,cvPoint(dst->width-120,20),&font,cvScalar(0,0xff));
    cvPutText(dst,dspStr2,cvPoint(dst->width-180,80),&font,cvScalar(0,0xff));
    cvPutText(dst,dspStr3,cvPoint(dst->width-120,40),&font,cvScalar(0,0xff));
    cvPutText(dst,dspStr4,cvPoint(dst->width-120,60),&font,cvScalar(0,0xff));
    //---------------------------------------------------------------------//
    cvShowImage( "AffineTransform", dst );
    PressKey = cvWaitKey();
    printf("%c is pressed\n",PressKey);
    switch(PressKey)
    {
    case '1':
    TLx++;
    break;
    case 'q':
    TLx--;
    break;
    case '2':
    TLy++;
    break;
    case 'w':
    TLy--;
    break;
    case '3':
    TRx++;
    break;
    case 'e':
    TRx--;
    break;
    case '4':
    TRy++;
    break;
    case 'r':
    TRy--;
    break;
    case '5':
    DLx++;
    break;
    case 't':
    DLx--;
    break;
    case '6':
    DLy++;
    break;
    case 'y':
    DLy--;
    break;
    case '7':
    angle++;
    break;
    case 'u':
    angle--;
    break;
    case '8':
    scale+=0.01;
    break;
    case 'i':
    scale-=0.01;
    break;
    case 27:
    cvReleaseImage(&dst);
    cvDestroyWindow("AffineTransform");
    cvReleaseMat(&rot_mat);
    cvReleaseMat(&warp_mat);
    return 0;
    case 's':
    cout<<"Input the filename:"<<endl;
    cin>>name[0];
    cvSaveImage( name[0], dstBak );
    cout<<name[0]<<" is saved."<<endl;
    break;
    default:
    cout<<"Input Error."<<endl;
    cout<<"Input 1 2 3 4 5 6 7 8 q w e r t y to change the coordinate."<<endl<<
    "Input u and i to change the angle and scale."<<endl<<"Input s to save the image."<<endl
    <<"Input the esc to quit."<<endl;
    break;
    }
    }
    cvDestroyWindow("AffineTransform");
    cvReleaseImage(&dst);
    cvReleaseMat(&rot_mat);
    cvReleaseMat(&warp_mat);
    return 0;

    }

程序执行结果:



原创粉丝点击