OPENCV图片批量更换文字

 团支书最头疼的事情莫过于假期收截图,例如当前的“暑假十课”,总有人久催不交

看这图片上交的模板,通过改变右上角名字就能做到偷天换日,那么一个班近30,十课一共300张图片,人工肯定是不现实的,但是OPENCV给我们提供了很好的环境。

方法:先采集RGB值,设置文字颜色阀值,然后将其与背景融合,再自行更换添加。


#include <sys/stat.h>
#include "opencv2/opencv.hpp"
#include "bits/stdc++.h"
#include "CvxText.h"
using namespace std;
using namespace cv;
Mat img;
void out_word();
string get_path(string path0, int num);
string output = "/home/rubo/机械五班";
string path;
string classmate[32] = {
        "白一", "蔡清", "奇一", "曾一", "一源", "一语", "陈远", "一凯", "一帅", "一凡", "陈瑶", "陈一", "大卓", "邓一",
        "董一", "方田", "冯一", "冯祺", "一旗", "付博", "一骏", "甘政", "一尚", "一鹏", "顾天", "黄一", "季姗",
        "刘一", "黎一", "一曦", "泽江", "仲钰",
};

static int ToWchar(char *&src, wchar_t *&dest, const char *locale = "zh_CN.utf8") {
    if (src == NULL) {
        dest = NULL;
        return 0;
    }
    setlocale(LC_CTYPE, locale);
    int w_size = mbstowcs(NULL, src, 0) + 1;
    if (w_size == 0) {
        dest = NULL;
        return -1;
    }
    dest = new wchar_t[w_size];
    if (!dest) {
        return -1;
    }
    int ret = mbstowcs(dest, src, strlen(src) + 1);
    if (ret <= 0) {
        return -1;
    }
    return 0;
}

void create_dir(string path0) {
    int isCreate = mkdir(path0.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRWXG | S_IRWXO);
    if (!isCreate)
        printf("create path:%s\n", path0.c_str());
    else
        printf("create path failed! error code : %s \n", path0.c_str());
}

void create_name(string path0, string name) {
    string path1 = path0;
    path1 = path1 + "/" + name;
    create_dir(path1);
}

void create_sum() {
    create_dir(output);
    for (int i = 0; i < 32; i++) {
        create_name(output, classmate[i]);
    }
}

int main() {
    out_word();
    create_sum();
    //printf("%d", strlen(classmate[0].c_str()));
    for (int i = 0; i < 32; i++) {
        for (int j = 1; j <= 10; j++) {
            string result_path = get_path(output + "/" + classmate[i], j);
            string from_path = "/home/rubo/图片/暑假十课";
            from_path = get_path(from_path, j);
            //cout<<from_path<<"   "<<result_path<<endl;
            img = imread(from_path);
            if (!img.data || img.channels() != 3) {
                fprintf(stderr, "read image fail\n");
                return -1;
            }
            CvxText text("/home/rubo/下载/chinese/iphone.ttf"); //指定字体
            Scalar size1{40, 0.5, 0.1, 0}; // (字体大小, 无效的, 字符间距, 无效的 }
            text.setFont(nullptr, &size1, nullptr, 0);
            char *str;
            int len = classmate[i].length();
            str = (char *) malloc((len + 1) * sizeof(char));
            classmate[i].copy(str, len, 0);
            str[len] = '\0';
            wchar_t *w_str;
            ToWchar(str, w_str);
            if (strlen(classmate[i].c_str()) >= 7) text.putText(img, w_str, Point(417, 172), Scalar(233, 68, 3));//三字
            else text.putText(img, w_str, Point(428, 172), Scalar(233, 68, 3));//两字
            imwrite(result_path, img);
        }
    }
    return 0;
}

string get_path(string path0, int num) {
    return path0 + "/" + to_string(num) + ".png";;
}


//该方法可能产生误检点,但在可容忍的错范围内
Mat GetRedComponet(Mat srcImg) {
    //如果直接对srcImg处理会改变main()函数中的实参
    Mat dstImg = srcImg.clone();
    Mat_<Vec3b>::iterator it = dstImg.begin<Vec3b>();
    Mat_<Vec3b>::iterator itend = dstImg.end<Vec3b>();
    for (; it != itend; it++) {
        if ((*it)[0] > 230 && (*it)[1] < 230 && (*it)[2] < 230)//对红色分量做阈值处理
        {
            //  (*it)[0] = 0;
            (*it)[1] = 0;
            (*it)[2] = 0;//红色分量保持不变
        } else {
            (*it)[0] = 0;
            (*it)[1] = 0;
            (*it)[2] = 0;
        }
    }
    return dstImg;
}

void Inpainting(Mat oriImg, Mat maskImg) {
    Mat grayMaskImg;
    Mat element = getStructuringElement(MORPH_RECT, Size(7, 7));
    dilate(maskImg, maskImg, element);//膨胀后结果作为修复掩膜
    //将彩色图转换为单通道灰度图,最后一个参数为通道数
    cvtColor(maskImg, grayMaskImg, COLOR_RGB2GRAY, 1);
    //修复图像的掩膜必须为8位单通道图像
    Mat inpaintedImage;
    inpaint(oriImg, grayMaskImg, inpaintedImage, 3, INPAINT_TELEA);

    imwrite(path, inpaintedImage);
}

string get_path(int num) {
    path = "/home/rubo/图片/暑假十课/";
    path = path + to_string(num) + ".png";
    return path;
}

void out_word() {
    Mat srcImg;
    for (int i = 1; i <= 10; i++) {
        get_path(i);
        srcImg = imread(path, 1);
        Mat imgComponet = GetRedComponet(srcImg);
        Inpainting(srcImg, imgComponet);
    }
}

玩归玩,闹归闹,十课的学习还是必要的

中文汉字库引用:https://download.csdn.net/download/qq_31261509/10750526

引用:https://blog.csdn.net/zx249388847/article/details/79332179

猜你喜欢

转载自blog.csdn.net/wu58430/article/details/119778909