前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV实现图像动画效果

OpenCV实现图像动画效果

作者头像
用户9831583
发布2022-06-16 14:46:48
7520
发布2022-06-16 14:46:48
举报
文章被收录于专栏:码出名企路

动画视频 http://mpvideo.qpic.cn/0bf2cuaaqaaaiialis2ajjpfafodbakqacaa.f10002.mp4?dis_k=a63837cae8019076438921df5dd82bf3&dis_t=1655361973&vid=wxv_1203069876135542785&format_id=10002&support_redirect=0&mmversion=false

完整代码

代码语言:javascript
复制
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <cstring>

#include <iostream>
using namespace std;
using namespace cv;


Mat Img_Rotate(Mat& img,float& scale,Point& center,float& angle,int& frame,
        int& time,bool process)
{
    Point _center;  
    _center.x = float(center.x);  
    _center.y = float(center.y);  
    Mat _img,__img;

    if(process)
    {
     //仿射变换 
     angle=-angle; 
      float frame_angle=angle/float(frame);
     //cout<<"frame_angle "<<frame_angle<<endl;
   
     //图像缩放
     float frame_scale=float(1.0-scale)/float(frame);
     //cout<<"frame_scale "<<frame_scale<<endl;
  
     for(int i=1;i<frame;i++)
    {   
        angle=i*frame_angle;
        Mat M = getRotationMatrix2D(_center, angle, 1); 
        warpAffine(img, _img, M, cvSize(img.cols, img.rows), CV_INTER_LINEAR); 

        scale=1.0-frame_scale*i;
        int  new_h = int(_img.rows * scale);
        int  new_w = int(_img.cols* scale) ;
        resize(_img, __img,Size(new_w,new_h),cv::INTER_LINEAR);
       //输出图像
       imshow("_img", __img);  
       waitKey(100);  
     
       }
    }

    else
    {
        Mat M = getRotationMatrix2D(_center, angle, 1); 
        warpAffine(img, _img, M, cvSize(img.cols, img.rows), CV_INTER_LINEAR);
        
        int  new_h = int(_img.rows * scale);
        int  new_w = int(_img.cols* scale) ;
        resize(_img, __img,Size(new_w,new_h),cv::INTER_LINEAR);
        //输出图像
       imshow("_img", __img);  
       waitKey(1000); 
    }
 

    return __img;  
}

// 获取指定像素点放射变换后的新的坐标位置  
Point Get_NewPos(const Point &src, const Point& center,
         float& scale, float& angle)  
{   
    //缩放旋转公式
    int x_origin = src.x - center.x;  
    int y_origin = src.y - center.y;  
    
    float x_transformed=scale*cos(angle)*x_origin - scale*sin(angle)*y_origin;
    float y_transformed=scale*sin(angle)*x_origin + scale*cos(angle)*y_origin;

    float x_new=x_transformed + center.x;
    float y_new=y_transformed + center.y;
     
    //返回
    Point dst;
    dst.x = cvRound(x_new);  
    dst.y = cvRound(y_new); 

    return dst;  
} 

void Process_Img(Mat& img,float& scale,float& theta,bool process,
            int& frame,int& time)
{   
  

    //旋转
    Point center( (float)(img.cols/2) , (float) (img.rows/2));
    float radian = (float) (theta/180.0 * CV_PI);
    
   // Mat _img = Img_Rotate(img, center, theta); 

    Mat _img = Img_Rotate(img,scale, center, theta,frame,time,process); 

    //计算原特征点在旋转后图像中的对应的坐标
    Point Left;  
    Left.x = 150;  
    Left.y = 200;  
    Point Right;  
    Right.x = 300;  
    Right.y = 200;  

    Point l= Get_NewPos(Left, center,scale, radian);  
    Point r = Get_NewPos(Right, center,scale, radian); 

    _img.at<unsigned char>(l.y, l.x) = 0;  
    _img.at<unsigned char>(r.y, r.x) = 0;  
  
}

int main(int argc,char** argv){

    
    //终端输入SRAFT参数
    if(argc!=7)
     {
         cout<<"需要输入6个值"<<endl;
         return -1;
     }

    cv::CommandLineParser parser(argc, argv,
            "{@img||}{@S||}{@R||}{@A||}{@F||}{@T||}");
   // Mat  img = parser.get<Mat>("@img");//错误
    Mat img=imread(argv[1],-1);
    float scale= parser.get<float>("@S") ;
    float theta= parser.get<float>("@R") ;
     bool  process= parser.get<bool>("@A") ;
     int   frame= parser.get<int>("@F") ;
     int   time= parser.get<int>("@T") ;
   cout<<"Scale "<<scale<<" Theta "<<theta<<" Process "<<process
            <<" Frame "<<frame<<" Time "<<time<<endl;
    
   
     //输入图像
    imshow("img",img);
    waitKey(1000);

    //防止丢失图片,填充图像
    int maxBorder =(int) (max(img.cols, img.rows)* 1.414 ); //即为sqrt(2)*max
    int dx = (maxBorder - img.cols)/2;
    int dy = (maxBorder - img.rows)/2;
    copyMakeBorder(img, img, dy, dy, dx, dx, BORDER_CONSTANT);
    

    Process_Img( img,scale, theta, process,frame,time);

 
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档