OpenCV图片动态特效显示(四)-- 中间扩张和栅格显示效果

2020-12-17 14:19:52 浏览数 (1)

学更好的别人,

做更好的自己。

——《微卡智享》

本文长度为2822,预计阅读8分钟

特效显示完结篇

今天这篇是使用OpenCV实现特效显示的最后一篇,主要是看看中间扩张和栅格显示。文章的最后我会把这一系列的源码放到GithHub上。

实现效果

上图中可以看到,左边两张图片是中间扩张的显示,分析是垂直方向和水平方向,右边的两张为栅格显示,也是通过水平和垂直方向设置。接下来就来看看这两种方式怎么实现的。

中间扩张显示

微卡智享

实现思路

#

思路

1

将图像分为两部分,将中间分界处显示在屏幕中央

2

从屏幕中央开始按设定的方向开始两边扫描

3

最后将图像完整的显示在屏幕上

核心代码

代码语言:javascript复制
//中间扩张显示
//参数:src 源图像,
//       width 图像宽度
//       height 图像长度
//       direction  方向  0-上下扩张  1-左右扩张
void midexpandshow(Mat src, int width, int height, int direction)
{
  Mat dst = Mat(src.size(), CV_8UC3);
  if (direction == 0) {
    setshowwindow(src, "midexpandshow0", 1, 100);
    //上下方向扩张
    for (int i = 1; i < height / 2;   i) {
      src(Rect(0, height / 2 - i, width, i))
        .copyTo(dst(Rect(0, height / 2 - i, width, i)));
      src(Rect(0, height / 2, width, i))
        .copyTo(dst(Rect(0, height / 2, width, i)));

      imshow("midexpandshow0", dst);
      waitKey(1);
    }
  }
  else {
    setshowwindow(src, "midexpandshow1", src.cols   1, 100);
    //左右方向扩张
    for (int i = 1; i < width / 2;   i) {
      src(Rect(width / 2 - i, 0, i, height))
        .copyTo(dst(Rect(width / 2 - i, 0, i, height)));
      src(Rect(width / 2, 0, i, height))
        .copyTo(dst(Rect(width / 2, 0, i, height)));

      imshow("midexpandshow1", dst);
      waitKey(1);
    }
  }
  waitKey(0);
}

线程调用

代码语言:javascript复制
  //中间扩张显示
  future<void> ftmidexpand0 = async(launch::async, midexpandshow, src, src.cols, src.rows, 0);
  future<void> ftmidexpand1 = async(launch::async, midexpandshow, src, src.cols, src.rows, 1);

栅格显示

微卡智享

实现思路

#

思路

1

设置一个栅格的宽度,将图像分为若干行

2

将奇数行组成一组,偶数行组成一组

3

显示奇数行时水平方向为从右到左,垂直方向是从上到下

4

显示偶数行时水平方向为从左到右,垂直方向是从下到上

核心代码

代码语言:javascript复制
//栅条特效
//参数   src  图像源
//       width  图像宽度
//       height 图像高度
//       gridwidth 每个栅格宽度
//       direction 方向   0-水平方向   1-垂直方向
void gridshow(Mat src, int width, int height, int gridwidth, int direction)
{
  Mat dst = Mat(src.size(), CV_8UC3);

  if (direction == 0) {
    setshowwindow(src, "gridshow0", src.cols * 2   1, 100);
    for (int i = 1; i < width   1; i = i   gridwidth) {
      //当I等于源图像宽度时,说明栅条全部遍历完成,直接显示原图像
      if (i == width) {
        cout << "over" << endl;
        src.copyTo(dst);
        imshow("gridshow0", dst);
        break;
      }
      if (i > width - gridwidth) i = width - gridwidth;
      for (int j = 0; j < height; j = j   2 * gridwidth) {
        if (j > height - 2 * gridwidth) j = height - 2 * gridwidth;
        //奇数行从右往左
        src(Rect(0, j, i, gridwidth))
          .copyTo(dst(Rect(width - i, j, i, gridwidth)));

        //偶数行从左往右
        int k = j   gridwidth;

        src(Rect(width - i, k, i, gridwidth))
          .copyTo(dst(Rect(0, k, i, gridwidth)));

        imshow("gridshow0", dst);
        waitKey(1);
      }
    }
  }
  else {
    setshowwindow(src, "gridshow1", src.cols * 3   1, 100);
    for (int i = 1; i < height   1; i = i   gridwidth) {
      //当I等于源图像宽度时,说明栅条全部遍历完成,直接显示原图像
      if (i == height) {
        cout << "over" << endl;
        src.copyTo(dst);
        imshow("gridshow1", dst);
        break;
      }
      if (i > height - gridwidth) i = height - gridwidth;
      for (int j = 0; j < width; j = j   2 * gridwidth) {
        if (j > width - 2 * gridwidth) j = width - 2 * gridwidth;
        //奇数列从上往下
        src(Rect(j, height - i, gridwidth, i))
          .copyTo(dst(Rect(j, 0, gridwidth, i)));

        //偶数列从下往上
        int k = j   gridwidth;

        src(Rect(k, 0, gridwidth, i))
          .copyTo(dst(Rect(k, height - i, gridwidth, i)));

        imshow("gridshow1", dst);
        waitKey(1);
      }
    }
  }
  waitKey(0);
}

线程调用

代码语言:javascript复制
  //栅格显示
  future<void> ftgridshow0 = async(launch::async, gridshow, src, src.cols, src.rows, 18, 0);
  future<void> ftgridshow1 = async(launch::async, gridshow, src, src.cols, src.rows, 18, 1);

代码地址

https://github.com/Vaccae/OpenCVImageEffect.git

0 人点赞