利用c++与opencv将文本、图像加密进另一张图片中

因为水平有限基本只利用了c++与opencv非常浅显简单的东西,实现所谓加密的方式是将文本或者图像的相关数据变为01编码,根据所得01编码影响载体图片的RGB数据,在测试下面代码时记得配置opencv

文本加密进载体图像
这是我所用的文本:
In the Age of Ancients,The
world was unformed,shrouded by fog.A land of grey crags,archtrees,and
everlasting dragons
But then there was Fire.And with Fire came
Disparity.Heat and cold,life and death,and of course…Light and Dark.
Then,from the Dark,They came,and found the
Souls of Lords within the flame.
Nito,the First of the Dead.
The Witch of Izalith,and herdaughters of Chaos.
Gwyn,the Lord of Sunlight,and his faithful knights.
And the furtive pygmy,so
easily forgotten.
With the Strength of Lords,they challenged the
dragons.
Gwyn’s mighty bolts peeled apart their stone
scales.The witches weaved great firestorms.Nito unleashed a miasma of death and
disease.
And Seath the Scaleless betrayed his own,and
the dragons were no more.Thus began the Age of Fire…But soon,the flames
will fade,and only Dark will remain.Even now,there are only embers,and man
sees not light,but only endless nights.
And amongst the living are seen,carriers ofthe accursed Darksign.,

首先是将文本中的数据提取转化为所需要的形式,从文本文件每录入一个字符,便将之转化为ASICII码对应的数字,再转化为01编码,因为ASCII码表示的最大符号~才126,所以将之写成8位的01编码完全够表示,我这里是先将01编码存储于一个8位的初始化为0的数组中,然后再赋值给一个大数组,同时设立一个初始化为0的变量,每当往大数组中赋一位值时便加一,用于记录需要塞进载体图片的数据的大小,之所以全是英文,是因为汉字是用两个位表示的,不能直接处理,要用到wchar等数据类型,这对于我有点复杂,做这个的时候又赶时间懒得研究,所以便调整成全英文的形式。

之所以设立一个大数组,则只是我为了应付作业偷懒而为,可以尝试改为动态链表的方式,若改为动态链表,则对大数组中有效数据终点的处理估计会更好

然后进行将数据塞进载体图片的操作,首先,从第8个像素开始,每当处理一个像素前,都预先将之RGB值变为偶数(RGB值减去其和2的余数),然后根据前面所得大数组的01编码数据按B、G、R的顺序(之所以要用BGR的顺序是因为在opencv中图像表示RGB数据的三项的数组[0]、[[1]]、[[2]]是按这个顺序的)依次改变像素RGB值的奇偶性(如果当前大数组数据是0,则B、G、或R值不变,为1,则则B、G、或R值加一)当前像素的RGB三个值都用完后则换下一个像素,2+2/3个像素表示一个文本文件中的字符。

在将大数组中的有效数据都录入完后,也将用于记录需要塞进载体图片的数据的大小的变量变为01编码再利用同样的方式录入图片前7个像素中,用前7个像素来表示塞进载体图片的数据的大小的话,则最多可表示2,097,151‬个01位,也就是约26w个字符

而在这里,我犯了一个错误,因为偷懒,所以十进制数据转换为二进制的数据的函数我是网络上随便找的一个,而这个函数是以整数形式保存二进制数据的,我只是根据需要在后面加了个整数拆分成数组的函数,例如50利用这个函数转化为二进制后为整数"11 0010",在先前ASCII码的转换这步中因为数据小,所以还正常,而在这里,直接将记录大小的变量换算成01编码用整数保存的话数字会特别大,会远大于2147483647这个int类型所能表示的最大的正数,而在找出这个错的过程中设立了cashfile.txt文件用于将提取的01编码保存下来,供我检测是那一部分出的错误,在找出这个错误后,重新编写了二进制转换函数,直接将ASCII码对应的数字转化为数组存储的01编码,这样我就不用再调用二进制转换函数后再调用整数拆分的函数了,省了整数拆分的步骤,算是意外之喜了

图像加密进载体图像
这与文本加密进载体图像的方式类似,先利用opencv技术将要加密的图像加载到内存中,读取该图像的长宽用9位表示,合用18位,依次存入大数组前18位中,然后按B、G、R的顺序依次读取每个像素rgb值,转化为8位01编码同样存储于大数组中,rgb值最大255正好8位够用

在将这个转化而来的数据塞进载体图像中可以直接利用前面加密文本时执行同样功能所用到的函数

而因为我偷懒直接设立的大数组,足足250w位,超过了所用IDE(VS2019)的默认堆栈大小(1MB),编译通不过,经过一番百度,将这大数组设为静态数组可以凑合凑合解决这个问题,在这里,我也才认识到或许可以用动态链表来做,就不会遇上这问题了,而且,250w个数组必然有非常多的位数用不到,很浪费内存,用动态链表也可以起到节约内存的作用

我测试所用的载体图片是分辨率为1920*1080p的bmp图像,它共有2,073,600‬个像素,8/3个像素存储一个数字,而三个数字组成待加密图像一个像素,所以待加密图像像素数不能大于259200,

之所以使用bmp图像而不使用使用频率更大的jpeg图像是因为后者会有压缩,造成误差,十分影响加密数据后对数据的解密

数据的解密
数据解密只需记住载体图像前七个像素用于存储数据量大小,要是解密出图像的话第8到第13个像素还用于存储图像大小,其余都是加密的反操作

确认加密有效
以加密图像为例,首先是待加密图像的相关数据:

加密后载体图像第8到第13个像素rgb值:

根据按bgr的顺序奇偶型分布可得01编码:
011101101 100111101
9位一组可换算出:237 317
所以存储的长宽数据正确,同理,易得其它数据也加密存储正确
而载体图像原图像与加密后对比(上为原图像):


待加密图像与解密后的图像的对比(左为原图像):

可以看出这两对图像间看不出区别,可惜这里不能张贴超过5M的图像和BMP图像,所以进行了压缩与格式转换

tupian.cpp

#include <iostream>
#include "head.h"
using namespace std;
int main()
{int i = 0, j = 0;cout << "选择功能,按对应的序号:" << endl;cout << "1:将文本加密进选中图片中" << endl;cout << "2:将图像加密进选中图片中(只支持240*320以下的图片)" << endl;cout << "3:将图片中的文本信息解密出来" << endl;cout << "4:将图片中所加密的其它图片解密出来\n" << endl;cin >> i;switch (i){case 1:      input_content_text();break;case 2:input_content_img();break;case 3:output_content_text();break;case 4:output_content_img();break;default:cout << "输入错误";    //goto L;break;}cout << "退出";
}

head.h

void input_content_text();
void input_content_img();
void input_content_audio();
void output_content_text();
void output_content_img();

function.cpp

#include <iostream>
#include <math.h>
#include <wchar.h>
#include <windows.h>
#include <stdlib.h>
#include <locale.h>
#include <fstream>
#include<opencv2/opencv.hpp>
//#pragma comment(lib,"opencv_world410d.lib")using namespace std;
using namespace cv;
#define LIMIT 500
#define BMLIMIT 7
#define MAXLIMUT 2500000
#define IMGPISIZE 240000void input_content_text();
int char_binary(char* a); //字符转二进制
int transfer(int x); //数字转二进制
int *transfer(int x,double a);
int transfer_(int x[],int a);//二进制转数字
void change_img(string );
void change_img(string img_path, int num[]);
int ch_int(char cash_data[BMLIMIT]);
void int_ch_out(int out_data[10000]);void input_content_text()
{int a=0,b=0, m[8];static int num[MAXLIMUT]  ;string img_path;char f_op1_name[100],f_op1_content[LIMIT],mid;for (int i = 0; i < MAXLIMUT; i++)num[i] = -1;std::cout << "输入想加密的文件的名字" << endl;cin >> f_op1_name;getchar();ofstream cashfile("cash.txt");//创建写入缓存文件对象ifstream fin(f_op1_name); //创建文件读取文件对象for (int i=0;fin;){//fin >> mid;//会滤掉空格fin.get(mid);a = char_binary(&mid);for (int j = 0; j < 8; j++)m[j] = 0;for (int j = 7;a>0; j--){m[j] = a % 10;a = a / 10;}//写成8位标准化b = mid;//cashfile << a << " ";//记录01值,便于检测for (int j = 0; j < 8; j++)cashfile << m[j];cashfile << " ";//记录8位标准化01值for (int j = 0; j < 8; j++)num[i++] = m[j];}cashfile.close();//关闭缓存文件std::cout << "输入图像路径与文件名:"<<endl;cin >> img_path;change_img(img_path,num);cashfile.clear();cashfile.close();//remove("cash.txt");//删除缓存文件fin.close();
}
void input_content_img()//240*320的图像
{int a = 0, b = 0;static int star_bgr[IMGPISIZE],num[MAXLIMUT];string img_path;char f_op1_name[100], f_op1_content[LIMIT], mid;for (int i = 0; i < MAXLIMUT; i++)num[i] = -1;for (int i = 0; i < IMGPISIZE; i++)star_bgr[i] = -1;std::cout << "输入想加密的文件的名字" << endl;cin >> f_op1_name;getchar();ofstream cashfile("cash.txt");//创建写入缓存文件对象ifstream fin(f_op1_name); //创建文件读取文件对象//图像读取Mat src;//int in_data_rgb[300000];int height, width, depth;//图像长宽深度/*for (int i = 0; i < 300000; i++)in_data_rgb[i] = -1;*/src = imread(f_op1_name);if (src.empty()){printf("can not load image \n");exit(0);}height = src.cols;width = src.rows;depth = src.step;//获取图形长宽深度,opencv中的mat类型star_bgr[0] = height;star_bgr[1] = width;cashfile << height << " " << width << " ";for (int x = 0, j = 0,k=2,b,g,r; x < width; x++)for (int y = 0; y < height; y++){//in_data_rgb[k] = src.at<Vec3b>(x, y)[0];//蓝//in_data_rgb[k+1] = src.at<Vec3b>(x, y)[1];//绿//in_data_rgb[k+2] = src.at<Vec3b>(x, y)[2];//红b = src.at<Vec3b>(x, y)[0];g = src.at<Vec3b>(x, y)[1];r = src.at<Vec3b>(x, y)[2];//cashfile << src.at<Vec3b>(x, y)[0] << " " << src.at<Vec3b>(x, y)[1] << " " << src.at<Vec3b>(x, y)[2] << " ";cashfile << b << " " << g << " " << r << endl;star_bgr[k] = b; star_bgr[k + 1] = g; star_bgr[k + 2] = r;k = k + 3;}cashfile.close();//关闭缓存文件//已经将需要加密的图像的长宽与各像素bgr值求出并存入数组star_bgr,现在需要将之转为01编码,长宽各用9位标识,合占18位,bgr值用8位int hw[18], bgr[8],mid1,mid2;mid1 = transfer(star_bgr[0]);mid2 = transfer(star_bgr[1]);for (int i = 0; i < 18; i++)hw[i] = 0;for (int i = 8; mid1>0; i--){hw[i] = mid1 % 10;mid1 = mid1 / 10;}for (int i = 17; mid2 > 0; i--){hw[i] = mid2 % 10;mid2 = mid2 / 10;}//可调节为另一个转换函数for (int i = 0; i < 18; i++)num[i] = hw[i];for (int i = 2,mid3=0,j=18; star_bgr[i] != -1;){mid3 = transfer(star_bgr[i++]);for (int i = 0; i < 8; i++)bgr[i] = 0;for (int i = 7; i >= 0; i--){bgr[i] = mid3 % 10;mid3 = mid3 / 10;}//写成8位标准值for (int a = 0; a < 8; a++)num[j++] = bgr[a];}std::cout << "输入图像路径与文件名:" << endl;cin >> img_path;change_img(img_path,num);cashfile.clear();cashfile.close();//remove("cash.txt");//删除缓存文件fin.close();}
void input_content_audio()
{}
void output_content_text()
{static int out_text[IMGPISIZE], num[MAXLIMUT];string img_name_out_path;Mat src;int height, width, depth,j=0;//图像长宽深度,从图片提取的01数组标识std::cout << "输入欲解密的图片路径名称:" << endl;cin >> img_name_out_path;for (int i = 0; i < MAXLIMUT; i++)num[i] = -1;for (int i = 0; i < IMGPISIZE; i++)out_text[i] = -1;src = imread(img_name_out_path);//src = imread("C:\\Users\\xyz\\OneDrive - dlmu.edu.cn\\实验代码\\tupian\\img.bmp");if (src.empty()){printf("can not load image \n");exit(0);}height = src.cols;width = src.rows;depth = src.step;//提取加密信息std::wcout << "图片已加载进内存,开始解密" << endl;int len[21],lenth=0;for (int y = 0,j=0; y <= 6; y++){for (int s = 0,bgr=0; s < 3; s++){bgr = src.at<Vec3b>(0,y)[s];if (bgr % 2 == 0)len[j++] = 0;elselen[j++] = 1;}}std::cout << "数据长度信息提取" << endl;lenth = transfer_(len, 21);//提取数组长度信息//std::cout << "\n数组长度求出" <<lenth<< endl;for (int x = 0, y = 7; j<lenth; x++){for (; y < height; y++){for (int s = 0,mid; s < 3; s++){mid = src.at<Vec3b>(x, y)[s];if (mid % 2 == 0)num[j++] = 0;elsenum[j++] = 1;}}y = 0;}std::cout << "信息提取完成,开始处理" << endl;
//后面处理提取的信息int intchar[8];for (int i = 0,j=0; i < lenth; ){for (int a = 0; a < 8; a++)intchar[a] = num[i++];out_text[j++] = transfer_(intchar, 8);}int_ch_out(out_text);cout << "信息解密完成" << endl;
}
void output_content_img()
{static int out_img[IMGPISIZE], num[MAXLIMUT];string img_name_out_path;Mat src;//int out_data[MAXLIMUT];int height, width, depth,j=0;//图像长宽深度std::cout << "输入欲解密的图片路径名称:" << endl;cin >> img_name_out_path;for (int i = 0; i < MAXLIMUT; i++)num[i] = -1;for (int i = 0; i < IMGPISIZE; i++)out_img[i] = -1;src = imread(img_name_out_path);//src = imread("C:\\Users\\xyz\\OneDrive - dlmu.edu.cn\\实验代码\\tupian\\img.bmp");if (src.empty()){printf("can not load image \n");exit(0);}height = src.cols;width = src.rows;depth = src.step;//获取图形长宽深度,opencv中的mat类型std::cout << "图片已加载进内存,开始解密" << endl;int len[21], lenth = 0;for (int y = 0, j = 0; y <= 6; y++){for (int s = 0, bgr = 0; s < 3; s++){bgr = src.at<Vec3b>(0, y)[s];if (bgr % 2 == 0)len[j++] = 0;elselen[j++] = 1;}}std::cout << "数据长度信息提取" << endl;for (int i = 0; i < 21; i++)cout << len[i] << " ";lenth = transfer_(len, 21);//提取数组长度信息//std::cout << "\n数组长度求出" <<lenth<< endl;for (int x = 0, y = 7; j < lenth; x++){for (; y < height; y++){for (int s = 0, mid; s < 3; s++){mid = src.at<Vec3b>(x, y)[s];if (mid % 2 == 0)num[j++] = 0;elsenum[j++] = 1;}}y = 0;}std::cout << "信息提取完成,开始处理" << endl;//后面处理提取的信息//for (int i = 0; i < 18; i++)//  cout << num[i] << " ";int heigh[9], wight[9], he_int, wi_int;for (int i = 0; i < 9; i++)heigh[i] = num[i];for (int i = 9; i < 18; i++)wight[i - 9] = num[i];he_int = transfer_(heigh, 9);wi_int = transfer_(wight, 9);//cout << he_int << " " << wi_int << endl;//开始计算剩下的数据int intchar[8];for (int i = 18, j = 0; i < lenth; ){for (int a = 0; a < 8; a++)intchar[a] = num[i++];out_img[j++] = transfer_(intchar, 8);}//建立缓存文件为了检测程序运行过程中是否有错ofstream cashfile("cash2.txt");//创建写入缓存文件对象for (int i = 0; i < IMGPISIZE;){cashfile << out_img[i] << " " << out_img[i+1] << " " << out_img[i+2] << endl;i = i + 3;}Mat img(wi_int, he_int, CV_8UC3);for (int x = 0, i = 0; x < wi_int; x++)for (int y = 0; y < he_int; y++)for (int s = 0; s < 3; s++)img.at<Vec3b>(x, y)[s] = out_img[i++];imwrite("out.bmp", img);std::cout << "解密完成";
}
//主要功能函数
void change_img(string img_path)
{Mat src;int height, width, depth;//图像长宽深度char cash_data[BMLIMIT],cash_data_mid;int cash_data_int[90000];ifstream icashfile("cash.txt");//创建读缓存文件对象for (int i = 0; i < BMLIMIT; i++)cash_data[i] = '#';//为数组赋值,以便区别录入内容与原数据for (int i = 0; i < 100000; i++)cash_data_int[i] = -1;for(int i=0,j=0,k=0;icashfile;i++){icashfile.get(cash_data_mid);if (cash_data_mid != ' ')cash_data[k++] = cash_data_mid;else{cash_data_int[j] = ch_int(cash_data);//字符整值转换j++;k = 0;for (int s = 0; s < BMLIMIT; s++)cash_data[s] = '#';//为数组赋值,以便区别录入内容与原数据}}//src = imread(img_path);//src = imread("C:\\Users\\xyz\\OneDrive - dlmu.edu.cn\\实验代码\\tupian\\img.bmp");if (src.empty()){printf("can not load image \n");exit(0);}height = src.cols;width = src.rows;depth = src.step;//获取图形长宽深度,opencv中的mat类型for(int x=0,j=0;x<width;x++)for (int y = 0; y < height; y++){if (cash_data_int[j] != -1){src.at<Vec3b>(x, y)[2] = cash_data_int[j];//修改r值j++;}else{src.at<Vec3b>(x, y)[0] = 0;src.at<Vec3b>(x, y)[1] = 0;src.at<Vec3b>(x, y)[2] = 0;//设立终点imwrite("after.bmp", src);goto M;//文档处理完毕,直接跳出多层循环}}
M:std::cout << "加密完毕";icashfile.close();
}
void change_img(string img_path, int num[])
{Mat src;int height, width, depth,num_len=0,j;//图像长宽深度数据长度src = imread(img_path);//src = imread("C:\\Users\\xyz\\OneDrive - dlmu.edu.cn\\实验代码\\tupian\\img.bmp");if (src.empty()){printf("can not load image \n");exit(0);}height = src.cols;width = src.rows;depth = src.step;//获取图形长宽深度,opencv中的mat类型//图片bgr值预先变为偶数,(奇数-1),加密时遇上1则+1,前7个像素用于存储数组大小信息//for (int y = 0, x = 7; y < height; y++)//{//    for (; x < width; x++)//   {//     src.at<Vec3b>(x, y)[0] = src.at<Vec3b>(x, y)[0] - src.at<Vec3b>(x, y)[0] % 2;//      src.at<Vec3b>(x, y)[1] = src.at<Vec3b>(x, y)[1] - src.at<Vec3b>(x, y)[1] % 2;//      src.at<Vec3b>(x, y)[2] = src.at<Vec3b>(x, y)[2] - src.at<Vec3b>(x, y)[2] % 2;//      for (int s = 0; s < 3; s++)//     {//         if (num[num_len] == 0)//          { //                num_len++;//              continue;//         }//         else if (num[num_len] == 1)//         {//             num_len++;//              src.at<Vec3b>(x, y)[s] = src.at<Vec3b>(x, y)[s] + 1;//            }//         else if (num[num_len] == -1)//内容终点//              goto ML;//          //num_len++;//        }// }// x = 0;//}cout << "图像已载入内存,开始处理" << endl;for (int x = 0, y = 7; x < width; x++){for (; y < height; y++){for (int s = 0, bgr; s < 3; s++){bgr = src.at<Vec3b>(x, y)[s];bgr = bgr - bgr % 2;src.at<Vec3b>(x, y)[s] = bgr;}//src.at<Vec3b>(x, y)[0] = src.at<Vec3b>(x, y)[0] - src.at<Vec3b>(x, y)[0] % 2;//src.at<Vec3b>(x, y)[1] = src.at<Vec3b>(x, y)[1] - src.at<Vec3b>(x, y)[1] % 2;//src.at<Vec3b>(x, y)[2] = src.at<Vec3b>(x, y)[2] - src.at<Vec3b>(x, y)[2] % 2;for (int s = 0, bgr; s < 3; s++){if (num[num_len] == 0){num_len++;continue;}else if (num[num_len] == 1){num_len++;bgr = src.at<Vec3b>(x, y)[s];bgr++;src.at<Vec3b>(x, y)[s] = bgr;//src.at<Vec3b>(x, y)[s] = src.at<Vec3b>(x, y)[s] + 1;}else if (num[num_len] == -1)//内容终点goto ML;//num_len++;}}y = 0;}num_len--;//*//std::cout << num_len << endl;
ML://内容加密完毕,处理并存储数组长度信息 6[2]->0[0]//std::cout << num_len << endl;int num_size[21],*num_lenth_2;unsigned long long num_lenth;num_lenth_2 = transfer(num_len,0.1);for (int i = 0; i < 21; i++){ num_size[i] = *num_lenth_2;num_lenth_2++;}//for (int i = 0; i <= 20; i++)//    cout << num_size[i] << " ";for (int y = 6,j=20; y >= 0; y--){for (int s = 0,bgr; s < 3; s++){bgr = src.at<Vec3b>(0,y)[s];bgr = bgr - bgr % 2;src.at<Vec3b>(0,y)[s] = bgr;}//src.at<Vec3b>(x, 0)[0] = src.at<Vec3b>(x, 0)[0] - src.at<Vec3b>(x, 0)[0] % 2;//src.at<Vec3b>(x, 0)[1] = src.at<Vec3b>(x, 0)[1] - src.at<Vec3b>(x, 0)[1] % 2;//src.at<Vec3b>(x, 0)[2] = src.at<Vec3b>(x, 0)[2] - src.at<Vec3b>(x, 0)[2] % 2;for(int s=2, bgr;s>=0;s--){ if (num_size[j] == 0){ j--;continue;}else if (num_size[j] == 1){bgr = src.at<Vec3b>(0,y)[s];// cout << bgr << endl;bgr++;src.at<Vec3b>(0,y)[s] = bgr;bgr = src.at<Vec3b>(0, y)[s];//cout << bgr << endl;//src.at<Vec3b>(0,y)[s] = src.at<Vec3b>(0,y)[s] + 1;j--;}//j--;}}imwrite("after.bmp", src);std::cout << "加密完毕";
}
//小函数
int char_binary(char *a)
{int i;i = *a;return transfer(i);
}
int transfer(int x)
{unsigned long long p = 1, y = 0, yushu;while (1){yushu = x % 2;x /= 2;y += yushu * p;p *= 10;if (x < 2){y += x * p;break;}}return y;
}//十进制二进制转换
int *transfer(int x, double a)
{int result[21] = { 0 };int mid[40] = { 0 }, i = 0, j = 0;//cout << "调用数组进制转换函数2" << endl;while (x != 0){mid[i++] = x % 2;x /= 2;}for (j = 20, i = 0; j >= 0; j--, i++)result[j] = mid[i];return result;
}
int transfer_(int x[],int a)
{int i = 0,sum=0;a--;for (; a >= 0; a--){sum =sum+ x[i] * pow(2, a);i++;}return sum;
}
int ch_int(char cash_data[BMLIMIT])
{int a = 0,b=0,num=0;int in_num[BMLIMIT];for (int i = 0; cash_data[i] != '#'; i++){in_num[i] = cash_data[i]-'0';b = i;}while(b>=0){num = num + in_num[b];b = b - 1;for (a = b; a >= 0; a--)in_num[a] = in_num[a] * 10;}return num;
}//字符数字转化为整型
void int_ch_out(int out_data[10000])
{char mid;ofstream fcout("after.txt");for (int i = 0; out_data[i] != -1; i++){mid = (char)out_data[i];fcout << mid;}fcout.close();}

利用c++与opencv将文本、图像加密进另一张图片中相关推荐

  1. 利用Python+OpenCV对图像加密/解密

    原文地址:利用Python.OpenCV对图像加密解密 | QuantumCloud蕴藏一个有趣.不难且实用的理论知识https://myblog.quantumcloud.top/2021/05/1 ...

  2. OpenCV 【十二】OpenCV如何扫描图像、利用查找表和计时

    目录 OpenCV如何扫描图像.利用查找表和计时 1.函数计算时间测试case 2. Mat图像的存储机理 3. 像素遍历的3--4种方式 4. 实例 OpenCV如何扫描图像.利用查找表和计时 如何 ...

  3. opencv处理dicom图像_图像处理|opencv| 利用opencv把照片变换成素描风格

    大家好我是阿猩学长,今天给大家利用图像处理库opencv来把图片转换为素描的风格. 其中利用的编程语言为C++. 话不多说先给大家看看实际的效果图. 原图 处理后的图片 原图 效果图 下面先给大家介绍 ...

  4. OpenCV之core 模块. 核心功能(1)Mat - 基本图像容器 OpenCV如何扫描图像、利用查找表和计时 矩阵的掩码操作 使用OpenCV对两幅图像求和(求混合(blending))

    Mat - 基本图像容器 目的 从真实世界中获取数字图像有很多方法,比如数码相机.扫描仪.CT或者磁共振成像.无论哪种方法,我们(人类)看到的是图像,而让数字设备来"看"的时候,则 ...

  5. 【笔记】opencv图像运算 图像加密

    图像加权和 可以用cv2.addWeighted()表示加权和 一个注意点: cv2.addWeighted(a,0.5,b,0.5,0)中两个图像的尺寸和通道数要相同,不然会报错. 示例: a = ...

  6. 医疗多模态预训练:如何利用非天然配对的医疗图像和文本做对比学习?

    ©PaperWeekly 原创 · 作者 | 王子丰 单位 | 伊利诺伊大学香槟分校 研究方向 | AI for healthcare EMNLP 2022 一共接收了我的三篇文章(两篇主会一篇 fi ...

  7. python opencv图像加密解密算法优化

    今天给大家带来的是图像加密解密算法的优化 这是我的设计思路 import cv2 import numpy as np aaa=cv2.imread("xxx.jpg",0) // ...

  8. 使用Python和OpenCV进行文本偏斜校正

    使用Python和OpenCV进行文本偏斜校正) 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python和OpenCV进行文本偏斜校正.给定图像包含未知角度的旋转文本块,需要通过以下方法纠 ...

  9. OpenCV:03图像的算数运算

    文章目录 掩膜 图像的算数运算 加法运算 利用掩膜遮盖相加结果 减法运算 乘法运算 除法运算 图片的融合 OpenCV的逻辑运算(位运算) 与运算`&` 花图像与十字掩膜做`与运算` 或运算` ...

最新文章

  1. 2018牛客网暑期ACM多校训练营(第十场)J(二分)
  2. 可变参数中size_t遇见的问题
  3. python三十二:os模块
  4. mybatis第一讲:初探mybatis实现简单的查询
  5. 《JAVA与模式》之状态模式
  6. r读取shape文件可视化_【R】提取 PCA 结果并利用 ggplot2 进行可视化
  7. 交流电路中的功率和功率因数
  8. [Cnoi2019]须臾幻境(LCT维护最大生成树+主席树/分块)
  9. orm框架选型问题_ORM问题
  10. 开工第一天,这个超时问题把我干趴下了
  11. SearchParams(URL获取参数)
  12. 编程工作枯燥、代码质量不高?华为云 MVP 来支招!
  13. redis tutorail
  14. hypermesh 复合材料_HyperMesh复合材料建模
  15. stc 串口收发 c语言,STC15W408AS串口通讯PC乱码
  16. c语言中函数指针用法,C语言函数指针的用法
  17. python转换 vcf到csv 小米通信录
  18. virtualxposed使用教程_VirtualXposed框架虚拟机——无需root体验xposed框架
  19. 程序员女友在京东被领导“潜规则”,竟然不回绝:表明非单身会影响绩效
  20. Mac搭建Flink集群

热门文章

  1. 如何用MATLAB代码求解偏微分方程组
  2. 结构方程模型分析流程
  3. 再论人与人的三大关系:生存关系、性关系和经济关系
  4. 短视频剪辑如何正确把握“节奏感”,三个小技巧助你快慢有序
  5. 转录因子详细介绍(motif)
  6. 大数据技术——Hadoop3.X入门搭建+安装调优(1.入门)
  7. windows system32和sysWOW64文件下面的dll丢失-解决方案
  8. 用K-Means算法处理wine数据集和wine_quality数据集
  9. Next.js v4.1.4 文档中文翻译
  10. Win11 22H2怎么退回之前版本?Win11回滚Win10系统教程(三种方法)