OpenCV图片动态特效显示(二)--渐显和马赛克显示

学更好的别人,

做更好的自己。

——《微卡智享》

本文长度为1907,预计阅读5分钟

前言

上一篇《OpenCV图片动态特效显示(一)--展开显示》介绍了图像的展开显示特效,这一篇我们还是在原来的Demo基础上加入图片的渐显和马赛克显示。

format,png

实现效果

format,png

上面的动图中可以看到,左边的是马赛克显示,右边的就是渐渐显示的效果,我们分别来说一下实现方式。

马赛克显示

format,png

微卡智享

实现思路

 

#实现步骤
1设置马赛克正方形的大小,将图像分割成多个马赛克
2把每个马赛克的左上角的坐标点存放到容器中
3把容器中的坐标点顺序随机打乱
4遍历已经打乱的容器逐步显示出图像

 

核心代码

//马赛克显示   
//参数:src 源图像, 
//      width 源图像宽度, 
//      height 源图像高度,
//      sidelength 马赛克的边长
//思路:1.根据设置的边长定义图像中马赛克的正方形小块,
//        把每个小块的左上角坐标记录下来存放到vector的容器中
//      2.然后把vector的容器顺序打乱
//      3.遍历容器里的坐标显示出图像
void mosaicshow(Mat src, int width, int height, int sidelength)
{
  Mat dst = Mat(src.size(), CV_8UC3);
  //定义坐标点容器
  vector<Point2f> vtpoints;


  //遍历图像将正方形小块左上角点存到容器中
  for (int col = 0; col < width; col = col + sidelength) {
    for (int row = 0; row < height; row = row + sidelength) {
      //如果宽度超出图像最右边的正方形点后设置最右边点
      if (col > width - sidelength) {
        col = width - sidelength;
      }
      //如果高度超出图像最下面的正方形高度同上原理
      if (row > height - sidelength) {
        row = height - sidelength;
      }
      //将坐标点存入到容器中
      vtpoints.push_back(Point2f(col, row));
    }
  }


  //打乱容器内的坐标点
  random_shuffle(vtpoints.begin(), vtpoints.end());


  //遍历容器显示每个马赛克
  for (Point2f pt : vtpoints)
  {
    src(Rect(pt.x, pt.y, sidelength, sidelength))
      .copyTo(dst(Rect(pt.x, pt.y, sidelength, sidelength)));
    imshow("mosaicshow", dst);
    waitKey(1);
  }
  waitKey(0);
}


format,png

渐显

format,png

微卡智享

实现思路

 

#实现步骤
1先从源图复制一个目标图像出来
2记录下源图像中每个像素点的值
3循环从黑到白的遍历(n=1....256)
4遍历的过程中把每个像素点的值*n/256再显示出来

 

核心代码

//图像渐显  
//参数:Mat 源图像,
//      width图像宽度, 
//      height图像高度
//思路:1.记录下图像每个像素点的像素值,显示的时候先将屏幕置黑
//      2.循环显示图像N次,每次显示像素值为N/256倍
void graduallyshow(Mat src, int width, int height)
{
  Mat dst;
  dst = src.clone();
  //考虑到三通道RGB的问题,所以宽度这里要乘3
  int tmpwidth = width * 3;
  for (int n = 1; n < 256; ++n) {
    for (int row = 0; row < height; ++row) {
      uchar* data1 = src.ptr<uchar>(row);
      uchar* data2 = dst.ptr<uchar>(row);


      for (int col = 0; col < tmpwidth; ++col) {
        data2[col] = data1[col] * n / 256;
      }
    }
    imshow("graduallyshow", dst);
    waitKey(1);
  }
  cout << "graduallyshow" << endl;
  waitKey(0);
}


format,png

format,png

线程调用

调用代码

  //图像渐显
  future<void> ftgradually = async(launch::async, graduallyshow, src, src.cols, src.rows);


  //马赛克显示
  future<void> ftmosaic = async(launch::async, mosaicshow, src, src.cols, src.rows, 20);


实现开头同时显示的方式还是用到了线程,也是上一篇中我们已经用到过的。

format,png

扫描二维码

获取更多精彩

微卡智享

format,png

「 往期文章 」

OpenCV图片动态特效显示(一)--展开显示

OpenCV实现图像转换为素描效果

C++ OpenCV输出中文

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Vaccae

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

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

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

打赏作者

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

抵扣说明:

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

余额充值