使用OpenCV制作一个动图表情包

最近和这个人聊天的过程中,她发了一张表情包,如下:

我第一反应是,我可以用学过的 OpenCV 知识实现这个效果。

说干就干,于是我花了一个小时实现了。

我的大体思路是:先拿到一张图片进行二值化处理,然后用我学过的 cv::findContours 函数找到轮廓,然后等间距地取不同数量的轮廓上的点并把它们连起来就行了。是不是很简单?

按照这个思路,再做一些细节上的处理,就大功告成了!

所使用的图片:

请添加图片描述

完整代码如下:

#include 
#include 

static std::vector<std::vector<cv::Point>> contours;
static cv::Mat drawer; 
static cv::Mat src,bin_img;

void drawContours(){
    
    drawer=cv::Mat::zeros(src.size(),CV_8UC3);
    
    static int add_val=0;
    static int pts_num=3;
    if(pts_num==3) add_val=1;
    else if(pts_num==150) add_val=-1;
    pts_num+=add_val;

    printf("%d\n",pts_num);

    for(auto this_contour:contours){
        int step=this_contour.size()/pts_num;
        if(step<1) step=1;
        // int step=1;
        int i;
        for(i=step;i<this_contour.size();i+=step){
            cv::line(drawer,this_contour[i-step],this_contour[i],cv::Scalar(255,255,255),1);
        }
        if(i>=this_contour.size())
            i=this_contour.size()-step;
        cv::line(drawer,this_contour[i-1],this_contour[0],cv::Scalar(255,255,255),1);
    }
    cv::imshow("result",drawer);
    cv::waitKey(2000/pts_num);
}

int main(int, char**) {
    src=cv::imread("../1.png",cv::IMREAD_GRAYSCALE);
    cv::resize(src,src,cv::Size(640,480));
    
    cv::threshold(src,bin_img,180,255,cv::THRESH_BINARY);

    cv::findContours(bin_img,contours,cv::RETR_LIST,cv::CHAIN_APPROX_NONE);
    while(1)
        drawContours();
}

运行效果:

(然后这个人还嫌弃我做得太丑了,真是气死我了!!所以我在这里一定要把她挂出来!!!

你可能感兴趣的:(一些小想法,opencv,计算机视觉,图像处理,c++,算法)