【深度好文】图像的特效显示

最近在学习B站天津理工大学杨淑莹老师的国家级精品课《数字图像处理》,这个老师的课程通俗易懂,值得推荐。直接B站搜索课程名字即可。
感兴趣的童鞋可以一起学习,共同进步。
在这里插入图片描述
本文针对常见的图像特效显示进行了归纳整理,并给出相关代码实现。

01 图像扫描显示特效

【效果】 从上往下扫描示例
从上往下扫描示例
【原理】
从图像的一侧(上下左右)扫描,实质是通过不断设置改变显示的ROI区域来实现的。
【实现】


void move_from_up(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;
  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());

  for(int i=0;i<height;i++)
  {
    cv::Rect src_roi = cv::Rect(0,i,width,1);
    cv::Rect dst_roi = cv::Rect(0,i,width,1);
    src_image(src_roi).copyTo(dst_image(dst_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

【其他示例】
从左往右扫描示例
在这里插入图片描述
从右往左扫描示例
在这里插入图片描述
从下往上扫描示例
在这里插入图片描述

02 图像渐显和渐隐特效

【效果】 图像渐显示例
在这里插入图片描述
【原理】
渐显和渐隐实质是改变图像像素的灰度值,我们知道图像的灰度值介于【0,255】之间,显示时每次显示像素值的n/255倍即可。。
【实现】

void fade_in(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;
  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());  

  for(int i=0;i<256;i++)
  {
    uchar *pBegin = src_image.ptr<uchar>(0);
    uchar *pDst = dst_image.ptr<uchar>(0);
    uchar *pEnd = pBegin + width * height * 3;
    for(;pBegin<pEnd;pBegin++,pDst++)
      *pDst = (uchar)(*pBegin * (i/255.0));
  
    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

【其他示例】
图像渐隐示例
在这里插入图片描述

03 图像平移特效

【效果】 图像从上往下平移示例
在这里插入图片描述
【原理】
图像的平移特效可以通过每次改变设置ROI的宽和高来实现。同时需要注意的是显示时的顺序,比如上图从上往下平移时,首先显示的是图像下面的部分,然后随着ROI区域的增大,逐渐显示全部的图像区域。
【实现】


void trans_from_up(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;
  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());

  for(int i=1;i<height;i++)
  {
    cv::Rect src_roi = cv::Rect(0,height-1-i,width,i);
    cv::Rect dst_roi = cv::Rect(0,0,width,i);
    src_image(src_roi).copyTo(dst_image(dst_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

【其他示例】
图像从右往左平移示例
在这里插入图片描述
图像从左往右平移示例
在这里插入图片描述
图像从下往上平移示例
在这里插入图片描述

04 图像沿中心线扩展特效

【效果】 图像从中心往上下扩展示例
在这里插入图片描述

【原理】
图像的沿中心线扩展特效可以分为从中心向上下两侧扩展,从中心向左右两侧扩展以及从中心向四周扩展三种方式,从中心向上下扩展其实现可以通过将图像分为上下两部分,将上下分界处显示在中间,然后同时向上和向下扫描即可快速实现。
【实现】


void trans_to_up_down(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;
  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());
  int half = height / 2;

  for(int i=0;i<half;i++)
  {
    cv::Rect src_roi = cv::Rect(0,half-i,width,1);
    cv::Rect dst_roi = cv::Rect(0,half-i,width,1);
    src_image(dst_roi).copyTo(dst_image(src_roi));

    src_roi = cv::Rect(0,half+i,width,1);
    dst_roi = cv::Rect(0,half+i,width,1);
    src_image(dst_roi).copyTo(dst_image(src_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

【其他示例】
图像从中心往左右扩展示例
在这里插入图片描述
图像中心往四周扩展示例
在这里插入图片描述

05 图像沿对角线扩展特效

【效果】 图像从左上到右下扩张示例
在这里插入图片描述

【原理】
图像的沿对角线扩展特效可以分为 从左上到右下扩展,从右下到左上扩展,从左下到右上扩展以及从右上到左下扩展共四种方式。其中从左上到右下的实现原理为通过同时改变显示区域ROI的宽和高,来达到沿对角线扩展的效果。
【实现】


void display_from_up_left(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;

  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());
  for(int i=1;i<width;i++)
  {
    int w = i;
    int h = i * height/width;
    cv::Rect src_roi = cv::Rect(0,0,w,h);
    cv::Rect dst_roi = cv::Rect(0,0,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

【其他示例】
图像从左下到右上扩张示例
在这里插入图片描述
图像从右下到左上扩张示例
在这里插入图片描述
图像从右上到左下扩张示例
在这里插入图片描述

06 图像马赛克特效

【效果】 图像马赛克特效示例
在这里插入图片描述
【原理】
图像的马赛克特效原理为通过将图像划分为固定大小的小块,通过记录每个小块的起始位置,然后随机显示这些小块,即可在人类视觉系统中形成马赛克效果。
【实现】


void display_mosaic(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;
  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());
  int step = 16;
  std::vector<cv::Point2d> pt_list;

  for(int i=0;i<width;i+=step)
  {
    for(int j=0;j<height;j+=step)
    {
      if(i+step > width)
        i = width - step;
      if(j+step>height)
        j = height - step;
      pt_list.push_back(cv::Point2d(i,j));
    }
  }

  int pt_num = pt_list.size();
  std::random_shuffle(pt_list.begin(),pt_list.end());
  for(int i=0;i<pt_num;i++)
  {
    cv::Rect src_roi = cv::Rect(pt_list[i].x,pt_list[i].y,step,step);
    cv::Rect dst_roi = cv::Rect(pt_list[i].x,pt_list[i].y,step,step);
    src_image(src_roi).copyTo(dst_image(dst_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

07 图像由四周向中心切入特效

【效果】 图像沿对角线向中心切入特效示例
在这里插入图片描述
【原理】
图像的由四周向中心切入特效特效可以分为沿两条对角线向中心切入特效以及沿四条边向中心切入特效两种方式。通过参考上述05沿对角线扩展示例,可以由两条对角线四个方向同时切入即可上述效果。
【实现】

void display_from_four_corner(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;

  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());
  for(int i=1;i<=width/2;i++)
  {
    int w = i;
    int h = i * height/width;

    // right down
    cv::Rect src_roi = cv::Rect(width-1-w,height-1-h,w,h);
    cv::Rect dst_roi = cv::Rect(width-1-w,height-1-h,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
     // left down
    src_roi = cv::Rect(0,height-1-h,w,h);
    dst_roi = cv::Rect(0,height-1-h,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
    //right up
    src_roi = cv::Rect(width-1-w,0,w,h);
    dst_roi = cv::Rect(width-1-w,0,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
    //left up
    src_roi = cv::Rect(0,0,w,h);
    dst_roi = cv::Rect(0,0,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

【扩展效果】
在这里插入图片描述
【原理】

参考上述沿对角线切入示例,将切入起点更改为四条边的中心点。相应的代码实现如下。

【实现】

void display_from_side(cv::Mat &src_image)
{
  cv::Size size = src_image.size();
  int width = size.width;
  int height = size.height;
  cv::Mat dst_image = cv::Mat::zeros(size,src_image.type());

  for(int i=1;i<=width/2;i++)
  {
    int w = i;
    int h = i * height/width;

    // left up
    cv::Rect src_roi = cv::Rect(0,height/2-h,w,h);
    cv::Rect dst_roi = cv::Rect(0,height/2-h,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
    src_roi = cv::Rect(width/2-w,0,w,h);
    dst_roi = cv::Rect(width/2-w,0,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
    // right up
    src_roi = cv::Rect(width-1-w, height/2-h,w,h);
    dst_roi = cv::Rect(width-1-w, height/2-h,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
    src_roi = cv::Rect(width/2, 0,w,h);
    dst_roi = cv::Rect(width/2, 0,w,h);
    src_image(dst_roi).copyTo(dst_image(src_roi));
    //left down
    src_roi = cv::Rect(0, height/2,w,h);
    dst_roi = cv::Rect(0, height/2,w,h);;
    src_image(dst_roi).copyTo(dst_image(src_roi));
    src_roi = cv::Rect(width/2-w, height-h,w,h);
    dst_roi = cv::Rect(width/2-w, height-h,w,h);;
    src_image(dst_roi).copyTo(dst_image(src_roi));
    //right down
    src_roi = cv::Rect(width-1-w ,height/2,w,h);
    dst_roi = cv::Rect(width-1-w, height/2,w,h);;
    src_image(dst_roi).copyTo(dst_image(src_roi));
    src_roi = cv::Rect(width/2 ,height-h,w,h);
    dst_roi = cv::Rect(width/2, height-h,w,h);;
    src_image(dst_roi).copyTo(dst_image(src_roi));

    cv::imshow("dst",dst_image);
    cv::waitKey(1);
  }
}

08 总结

本文针对图像显示的一些常见特效进行了原理总结和代码实现,可以更好的加深我们对图像基础理论知识的理解。

关注公众号《AI算法之道》,获取更多AI算法资讯.
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵卓不凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值