基于图片的信息隐藏与显示

本文介绍了一种使用OpenCV进行车牌识别并将其信息隐藏在图片中的简单加密方法。通过纯C++、Java或C#实现,展示了如何将文本信息嵌入到图片中,使得在不改变图片外观的情况下,信息依然可以被读取。该技术适用于需要保护敏感信息的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在做一个车牌识别项目时想到的,但是把这代码拿给老师看了才知道这是比较简单的加密了(本来还以为想到什么好点子),所以拿出了和大家分享下。这只是利用了Opencv而已,你也可以用纯c++,java,C#来写,只不过我做车牌识别时恰巧用到了Opencv所以就直接用了。关于opencv的安装os里面有篇文章写得不错http://my.oschina.net/gujianhan/blog/162120,在我这代码里除了对像素的操作借助了opencv其他的还都是c++。所以没有下面评论说的头文件也不是问题。运行之后你会发现两张图片完全一样,但是信息就是隐藏在图片里了

#include<iostream>
#include"highgui.h"
#include<vector>
#include"cv.h"
#include<fstream>
using namespace std;
using namespace cv;
void readInformation(IplImage * imgSrc);
void roatedImage(IplImage *imgSrc){
    CvScalar t1,t2;
    IplImage *imgCopy=cvCreateImage(cvSize(imgSrc->height,imgSrc->width),
        imgSrc->depth,imgSrc->nChannels);
    for(int i=0;i<imgSrc->height;i++)
        for(int j=0;j<imgSrc->width;j++){
            t1=cvGet2D(imgSrc,i,j);
            cvSet2D(imgCopy,j,i,t1);
        }
        cvSaveImage("D:\\Opencv\\testSave.jpg",imgCopy);
}
int addInformation(IplImage *imgSrc){
    CvScalar t1,t2;
    IplImage *imgCopy=cvCreateImage(cvSize(imgSrc->width,imgSrc->height),
        imgSrc->depth,imgSrc->nChannels);
    string str="";
    cout<<"请输入你想要加入的文本:"<<endl;
    getline(cin,str);
    int length=0;
    for(int i=0;i<imgSrc->height;i++)
        for(int j=0;j<imgSrc->width;j++){
            if(length<str.length()){
                t1=cvGet2D(imgSrc,i,j);
                t1.val[0]=str[length];
                cvSet2D(imgCopy,i,j,t1);
                length++;
            }
            else{
            t1=cvGet2D(imgSrc,i,j);
            cvSet2D(imgCopy,i,j,t1);
            }
        }
        Mat mat(imgCopy);
        string path;
        cout<<"输入图片保存路径(请保存为png格式):"<<endl;
        cin>>path;
        imwrite(path.c_str(),mat);
        return str.length();
}
void readInformation(IplImage * imgSrc,int wordNumber){
    int length=0;
    CvScalar t1,t2;
    for(int i=0;i<imgSrc->height;i++){
        for(int j=0;j<imgSrc->width;j++){
            if(length<wordNumber){
                t1=cvGet2D(imgSrc,i,j);
                char ch=(int)t1.val[0];
                cout<<ch;
                length++;
            }
            if(length>=wordNumber)
                break;
        }
        }
}
///*
//改进函数
//*/
string toBinary(int num){
    string str="";
    do{
        int remaider=num%2;
        num=num/2;
        str+=to_string(remaider);
    }while(num);
    string str2="";
    for(int i=str.length()-1;i>=0;i--)
        str2+=str[i];
    int addNum=7-str2.length();
    string str3="";
    for(int i=0;i<addNum;i++)
        str3+="0";
    str2=str3+str2+"00";
    return str2;
}
 
char toChar(string strNumber){
    strNumber=strNumber.substr(0,7);
    int sum=0;
    for(int i=0;i<strNumber.length();i++)
        sum+=(strNumber[i]-'0')*pow(2,(strNumber.length()-i-1));
    char ch=sum;
    return ch;
}
 
int addInformation3(IplImage *imgSrc){
    CvScalar t0,t1,t2;
    IplImage *imgCopy=cvCreateImage(cvSize(imgSrc->width,imgSrc->height),
        imgSrc->depth,imgSrc->nChannels);
    string str="";
    cout<<"请输入你想要加入的文本用#结束:"<<endl;
    getline(cin,str);
    vector<string> vestr_3;
    for(int i=0;i<str.length();i++)
    {
        string tmp=toBinary(str[i]);
        string tmp1=tmp.substr(0,3);
        string tmp2=tmp.substr(3,3);
        string tmp3=tmp.substr(6,3);
        vestr_3.push_back(tmp1);
        vestr_3.push_back(tmp2);
        vestr_3.push_back(tmp3);
    }
    int length=0;
    for(int i=0;i<imgSrc->height;i++)
        for(int j=0;j<imgSrc->width;j++){
            if(length<vestr_3.size()*3)
            {
                t1=cvGet2D(imgSrc,i,j);
                string tmp=vestr_3[length/3];
                for(int m=0;m<3;m++)
                {
                    if(tmp[m]=='1')
                        t1.val[m]+=1;
                    if(tmp[m]=='0')
                        t1.val[m]-=1;
                }
                cvSet2D(imgCopy,i,j,t1);
                length+=3;
            }
            else
            {
            t1=cvGet2D(imgSrc,i,j);
            cvSet2D(imgCopy,i,j,t1);
            }
            }
         
        Mat mat(imgCopy);
        string path;
        cout<<"输入图片保存路径(请保存为png格式):";
        cin>>path;
        imwrite(path.c_str(),mat);
        return str.length();
         
}
void readInformation3(IplImage * imgSrc,IplImage* imgCopy){
    int length=0;
    CvScalar t1,t2;
    int count2=0;
    string tmp2="";
    for(int i=0;i<imgSrc->height;i++){
        for(int j=0;j<imgSrc->width;j++){
            t1=cvGet2D(imgSrc,i,j);
            t2=cvGet2D(imgCopy,i,j);
            string tmp="";
            tmp+=to_string(t2.val[0]-t1.val[0]>0?1:0);
            tmp+=to_string(t2.val[1]-t1.val[1]>0?1:0);
            tmp+=to_string(t2.val[2]-t1.val[2]>0?1:0);
            if(count2<3){
            tmp2+=tmp;
            count2++;
            }
            if(count2==3){
            char ch=toChar(tmp2);
            if('#'==ch)return ;
            cout<<ch;
            count2=0;
            tmp2="";
        }
        }
        }
}
void menu(){
    int choice;
    cout<<"****************************NUPT B12 NIIT  Liyao**************************"<<endl;
    cout<<"**********1:选择图片加入信息****2:读取图片里面的信息****3:退出**********"<<endl;
    string path;
    string path2;
    cin>>choice;
    switch(choice){
    case 1:
        {
        cout<<"输入原图片的路径:";
        cin>>path;
        getchar();
        IplImage *imgSrc=cvLoadImage(path.c_str(),-1);
        addInformation3(imgSrc);
        }
        break;
    case 2:
        {
        cout<<"输入原图片和改变后图片的路径:"<<endl;
        cout<<"原图片路径:";
        cin>>path;
        cout<<"改变后图片的路径:";
        cin>>path2;
        cout<<endl;
        IplImage *imgSrc2=cvLoadImage(path.c_str(),-1);
        IplImage *imgCopy=cvLoadImage(path2.c_str(),-1);
        readInformation3(imgSrc2,imgCopy);
        cout<<endl;
        }
        break;
    case 3:
        exit(1);
        break;
    default:
        cout<<"错误指令!"<<endl;
    }
}
int main(){
    do{
        menu();
    }while(1);
}

下面分别是我使用的原图片和改变后的图片以及程序运行截图:

转载请注明出处http://www.cnblogs.com/BasilLee/p/3741200.html。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值