团支书最头疼的事情莫过于假期收截图,例如当前的“暑假十课”,总有人久催不交
看这图片上交的模板,通过改变右上角名字就能做到偷天换日,那么一个班近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