OpenCV和MFC的超混沌图像加密

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV和MFC的超混沌图像加密相关的知识,希望对你有一定的参考价值。

文章目录

基于 openCV 和 MFC 的超混沌图像加密

项目链接

https://download.csdn.net/download/weixin_45525272/78561755

效果展示

加载图像

进行加密

进行解密

环境

  • 基于 openCV 与 MFC 的超混沌图像加密软件,openCV 提供图像读取、存储功能,通过 MFC 构建人机交互界面
  • 编译环境为 Visual Studio Community 2017
  • OpenCV 库版本 opencv-4.5.1-vc14_vc15

源代码

Encryption_MFCDlg.h: 头文件


// Encryption_MFCDlg.h: 头文件
//

#pragma once

// CEncryptionMFCDlg 对话框
class CEncryptionMFCDlg : public CDialogEx

// 构造
public:
	CEncryptionMFCDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum  IDD = IDD_ENCRYPTION_MFC_DIALOG ;
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedChooseImg();
public:


	//添加成员变量行列标号
	int count_n;
	int count_m;
	//原图、加密、解密图像数据
	cv::Mat lena;
	cv::Mat encryption_lena;
	cv::Mat decryption_lena;
	CProgressCtrl EnProgress;
	CProgressCtrl DeProgress;
	//缩放窗体链表
	CList<CRect, CRect&> m_listRect;

	afx_msg void DrawMat(cv::Mat & img, UINT nID);
	afx_msg void OnBnClickedEncrypting();
	afx_msg void OnBnClickedDecrypting();
	afx_msg void EncrytingMat(cv::Mat & Enimg, const double Enx_chaos[], const double Eny_chaos[]);
	afx_msg void DecrytingMat(cv::Mat & Deimg, const double Enx_chaos[], const double Eny_chaos[]);
	afx_msg void OnBnClickedSaveEncrypting();
	afx_msg void OnBnClickedSaveDecrypting();
	afx_msg void OnBnClickedLoadencryption2enWindow();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnBnClickedUnchangedChooseImg();
;
//数组循环右移函数声明
template <typename T>
void array_rightshift(std::vector<T> &a, int &N);
//数组循环右移函数定义
template <typename T>
void array_rightshift(std::vector<T> &a, int &N)

	//采用空间换时间,构建等长临时数组
	//将原数组后num_shift1位(移位位数)元素放置临时数组前面,将原数组前面的元素放置临时数组后面,将临时数组赋值给原数组
	int bitnum = static_cast<int>(a.size());
	int num_shift1 = N % bitnum;
	std::vector<T> temp(bitnum);
	for (int i = 0; i < num_shift1; i++)
	
		temp[i] = a[bitnum - num_shift1 + i];
	
	for (int j = 0; j < bitnum - num_shift1; j++)
	
		temp[j + num_shift1] = a[j];
	
	for (int k = 0; k < bitnum; k++)
	
		a[k] = temp[k];
	


Encryption_MFCDlg.cpp: 实现文件


// Encryption_MFCDlg.cpp: 实现文件
//

#include "stdafx.h"
#include "Encryption_MFC.h"
#include "Encryption_MFCDlg.h"
#include "afxdialogex.h"
#include <stdio.h>
#include<vector>
#include <cmath>
#include<algorithm>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#ifndef PI
#define PI 3.141592658
#endif

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx

public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum  IDD = IDD_ABOUTBOX ;
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
;

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)



void CAboutDlg::DoDataExchange(CDataExchange* pDX)

	CDialogEx::DoDataExchange(pDX);

//?
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CEncryptionMFCDlg 对话框



CEncryptionMFCDlg::CEncryptionMFCDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_ENCRYPTION_MFC_DIALOG, pParent)

	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);


void CEncryptionMFCDlg::DoDataExchange(CDataExchange* pDX)

	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EN_PROGRESS, EnProgress);
	DDX_Control(pDX, IDC_DE_PROGRESS, DeProgress);


BEGIN_MESSAGE_MAP(CEncryptionMFCDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_CHOOSE_IMG, &CEncryptionMFCDlg::OnBnClickedChooseImg)
	ON_BN_CLICKED(IDC_ENCRYPTING, &CEncryptionMFCDlg::OnBnClickedEncrypting)
	ON_BN_CLICKED(IDC_DECRYPTING, &CEncryptionMFCDlg::OnBnClickedDecrypting)
	ON_BN_CLICKED(IDC_SAVE_ENCRYPTING, &CEncryptionMFCDlg::OnBnClickedSaveEncrypting)
	ON_BN_CLICKED(IDC_SAVE_DECRYPTING, &CEncryptionMFCDlg::OnBnClickedSaveDecrypting)
	ON_BN_CLICKED(IDC_LOADENCRYPTION2EN_WINDOW, &CEncryptionMFCDlg::OnBnClickedLoadencryption2enWindow)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_UNCHANGED_CHOOSE_IMG, &CEncryptionMFCDlg::OnBnClickedUnchangedChooseImg)
END_MESSAGE_MAP()


// CEncryptionMFCDlg 消息处理程序

BOOL CEncryptionMFCDlg::OnInitDialog()

	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		
	

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
		
	//设置进度条En颜色
	::SendMessageA(EnProgress.GetSafeHwnd(),PBM_SETBARCOLOR,0,RGB(255, 250, 250));
	EnProgress.SetBarColor(RGB(67, 205, 128));
	//设置进度条De颜色
	::SendMessageA(DeProgress.GetSafeHwnd(), PBM_SETBARCOLOR, 0, RGB(255, 250, 250));
	DeProgress.SetBarColor(RGB(67, 205, 128));

	//获取所有窗口位置大小
	CRect rect;
	GetWindowRect(&rect);
	m_listRect.AddTail(rect);//对话框的区域
	CWnd* pWnd = GetWindow(GW_CHILD);//获取子窗体
	while (pWnd)
	
		pWnd->GetWindowRect(rect);//子窗体的区域
		m_listRect.AddTail(rect);           //CList<CRect,CRect> m_listRect成员变量
		pWnd = pWnd->GetNextWindow();//取下一个子窗体
	

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE


void CEncryptionMFCDlg::OnSysCommand(UINT nID, LPARAM lParam)

	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	
	else
	
		CDialogEx::OnSysCommand(nID, lParam);
	


// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CEncryptionMFCDlg::OnPaint()

	if (IsIconic())
	
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	
	else
	
		CDialogEx::OnPaint();
		CDialog::UpdateWindow();
	


HCURSOR CEncryptionMFCDlg::OnQueryDragIcon()

	return HCURSOR();


//选择图片控件响应函数
void CEncryptionMFCDlg::OnBnClickedChooseImg()

	// TODO: 在此添加控件通知处理程序代码
	CString picPath;   // 定义图片路径变量  

	CFileDialog dlg(true, _T("*.tiff;*.bmp; *.tif;*.jpg"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T("image files (*.tiff;*.bmp ;*.jpg;)|*.tiff;*.bmp; *.jpg |ALL Files (*.*) |*.*||"), NULL);

	//打开文件对话框的标题名
	dlg.m_ofn.lpstrTitle = _T("选择图片");
	if (dlg.DoModal() == IDOK)
	
		picPath = dlg.GetPathName();  //获取图片路径  
	
	//CString to string  使用这个方法记得字符集选用“使用多字节字符”,不然会报错  
	std::string picpath = picPath.GetBuffer(0);
	lena = cv::imread(picpath, cv::IMREAD_COLOR);
	if (lena.empty())
	
		MessageBox(_T("读取文件为空,请选择一张图像文件"));
		return;
	
	else if (lena.rows*lena.cols < 1024 * 1024)
	
		;
	
	else if (lena.rows*lena.cols < 2048 * 2048)
	
		lena = cv::imread(picpath, cv::IMREAD_REDUCED_COLOR_2);
	
	else if (lena.rows*lena.cols < 4096 * 4096)
	
		lena = cv::imread(picpath, cv::IMREAD_REDUCED_COLOR_4);
	
	else
	
		lena = cv::imread(picpath, cv::IMREAD_REDUCED_COLOR_8);
	

	SetDlgItemText(IDC_ImagePath, picPath);
	DrawMat(lena, IDC_ORIGINAL1);
	AfxMessageBox("图像读取完成");


void CEncryptionMFCDlg::OnBnClickedUnchangedChooseImg()

	// TODO: 在此添加控件通知处理程序代码
	CString picPath;   //定义图片路径变量  

	CFileDialog dlg(true, _T("*.tiff;*.bmp; *.tif;*.jpg"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T("image files (*.tiff;*.bmp ;*.jpg;)|*.tiff;*.bmp; *.jpg |ALL Files (*.*) |*.*||"), NULL);

	//打开文件对话框的标题名
	dlg.m_ofn.lpstrTitle = _T("选择图片");
	if (dlg.DoModal() == IDOK)
	
		picPath = dlg.GetPathName();  //获取图片路径  
	
	//CString to string  使用这个方法记得字符集选用“使用多字节字符”,不然会报错  
	std::string picpath = picPath.GetBuffer(0);
	lena = cv::imread(picpath, cv::IMREAD_COLOR);
	if (lena.empty())
	
		MessageBox(_T("读取文件为空,请选择一张图像文件"));
		return;
	
	SetDlgItemText(IDC_ImagePath, picPath);
	DrawMat(lena, IDC_ORIGINAL1);
	AfxMessageBox("图像读取完成");


//加密控件响应函数
void CEncryptionMFCDlg::OnBnClickedEncrypting()

	// TODO: 在此添加控件通知处理程序代码
	CString str_encryp_password;
	//从输入密码控件获取密码,存入str_encryp_passward
	GetDlgItem(IDC_ENCRYPTION_PASSWORD)->GetWindowText(str_encryp_password);
	if (lena.empty())
	
		AfxMessageBox("未载入图像,请先载入一张原始图像!");
		return;
	
	else if (str_encryp_password.IsEmpty())
	
		AfxMessageBox("密码为空,请重新输入8位密码!");
		return;
	
	else if (str_encryp_password.GetLength()!=8)
	
		AfxMessageBox("密码长度错误,请重新输入8位密码!");
		return;
	
	for(int i=0;i< str_encryp_password.GetLength();++i)
	
		if (str_encryp_password[i]<'0' || str_encryp_password[i]>'9')
		
			AfxMessageBox("密码数据类型错误,请输入范围在0-9之间的数字!");
			return;
		
	
	//动态申请混沌数组内存
	double *x_chaos = new double[lena.rows * lena.cols * lena.channels()];
	double *y_chaos = new double[lena.rows * lena.cols * lena.channels()];
	//结合图像特征信息初始化初值
	double tempx_last = 0.1*(str_encryp_password[0]-'0')+ 0.01*(str_encryp_password[1] - '0')图像加密解密基于matlab GUI混沌序列图像加密解密(含相关性检验)含Matlab源码 1862期

图像加密基于matlab GUI混沌系统图像加密解密含Matlab源码 1240期

图像加密基于matlab logistic混沌图像加密与解密含Matlab源码 1216期

图像加密基于matlab Logistic混沌+Arnold置乱图像加密含Matlab源码 1281期

图像加密基于matlab混沌算法图像加密解密含Matlab源码 1218期

图像加密基于matlab DNA混沌系统图像加密含Matlab源码 1190期