大数跨境
0
0

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

【深度好文】图像的特效显示 AI算法之道
2021-07-03
0
导读:本文针对图像显示的一些常见特效进行了原理总结和代码实现,可以更好的加深我们对图像基础理论知识的理解。


最近在学习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

总结


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

【声明】内容源于网络
0
0
AI算法之道
一个专注于深度学习、计算机视觉和自动驾驶感知算法的公众号,涵盖视觉CV、神经网络、模式识别等方面,包括相应的硬件和软件配置,以及开源项目等。
内容 573
粉丝 0
AI算法之道 一个专注于深度学习、计算机视觉和自动驾驶感知算法的公众号,涵盖视觉CV、神经网络、模式识别等方面,包括相应的硬件和软件配置,以及开源项目等。
总阅读195
粉丝0
内容573