#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<opencv.hpp>
#include<ctype.h>
using namespace std;
using namespace cv;
int Pretreat();
char str[100] = {0};
struct {
char c;
int count;
}kind[100];
typedef struct nn{
char character;
int weight;
int flag;
int parent;
int lchild;
int rchild;
}HaffNode;
typedef struct {
int bit[255];
int start;
int weight;
}Code;
void Haffman(int n, HaffNode *hafftree);
void HaffmanCode(HaffNode *hafftree, int n, Code *haffCode);
void preorder(HaffNode *hafftree, int n,int x,int y,int lenth);
void draw(int b, int g, int r, int flag, int x, int y,int lenth);
void Compression(Code *haffcode, int n);
void Translation();
Mat image(1000, 1000, CV_8UC3);
int main()
{
namedWindow("tree");
int i = 0, j;
int len = Pretreat();
HaffNode *haffman = (HaffNode *)malloc(sizeof(HaffNode)*(2*len-1));
Code *haffcode = (Code *)malloc(sizeof(Code)*len);
Haffman(len, haffman);
haffman;
HaffmanCode(haffman, len,haffcode);
FILE *fp = fopen("C:\\Users\\chenh\\Desktop\\ctest\\Codebook.txt", "w");
for (i = 0; i < len; i++)
{
fprintf(fp, "%c: ", haffman[i].character);
for (j = haffcode[i].start + 1; j < len; j++)
{
fprintf(fp,"%d", haffcode[i].bit[j]);
}
fprintf(fp,"\n");
}
fclose(fp);
draw(255, 255, 0, 2, 500, 50,150);
preorder(haffman, 2 * len - 2,500,50,150);
Compression(haffcode, len);
Translation();
}
int Pretreat()
{
int k = 0;
FILE *fp; int i, j,count,q,flag=0;
if ((fp = fopen("C:\\Users\\chenh\\Desktop\\ctest\\Input.txt", "r")) == NULL)
printf("failed to open file\n");
fgets(str, 200, fp);//读取到str中
for (i=0; i < strlen(str); i++)
{
count = 1; flag = 1;
for (j = i+1; j < strlen(str); j++)
{
if (str[i] == str[j])count++;
}
for (q = 0; q < 100; q++)
{
if (str[i] == kind[q].c) {
flag = 0;
break;
}
}
if (flag)
{
kind[k].c = str[i];
kind[k++].count = count;
}
}
return k;
}//生成kind 每个字符所对应的权值
void Haffman(int n, HaffNode *hafftree)
{
int i, j, m1, m2, x1, x2;
//初始化
for (i = 0; i < 2 * n - 1; i++)
{
if (i < n)
{
hafftree[i].character = kind[i].c;
hafftree[i].weight = kind[i].count;
}
else
hafftree[i].weight = 0;
hafftree[i].parent = 0; hafftree[i].flag = 0; hafftree[i].lchild = -1; hafftree[i].rchild = -1;
}
//构造非叶子节点
for (i = 0; i < n - 1; i++)
{
m1 = m2 = 1000;
x1 = x2 = 0;
for (j = 0; j < n + i; j++)
{
if (hafftree[j].weight < m1&&hafftree[j].flag == 0)
{
m2 = m1;
x2 = x1;//记录上次的
m1 = hafftree[j].weight;
x1 = j;//更新这次的
}
else if (hafftree[j].weight < m2&&hafftree[j].flag == 0)
{
m2 = hafftree[j].weight;
x2 = j;
}
}
//将找出的两颗最小书合并
hafftree[x1].parent = n + i;
hafftree[x2].parent = n + i;
hafftree[x1].flag = 1;
hafftree[x2].flag = 1;
hafftree[n + i].weight = hafftree[x1].weight + hafftree[x2].weight;
hafftree[n + i].lchild = x1;
hafftree[n + i].rchild = x2;
}
}
void HaffmanCode(HaffNode *hafftree, int n, Code *haffCode)//从叶子到到根节点的编码
{
int i, j, child, parent;
Code *temp=(Code *)malloc(sizeof(Code));
for (i = 0; i < n; i++)
{
temp->start = n - 1;
temp->weight = hafftree[i].weight;
child = i;
parent = hafftree[child].parent;
while (parent != 0)
{
if (hafftree[parent].lchild == child)
temp->bit[temp->start] = 0;//左0右1
else
temp->bit[temp->start] = 1;
temp->start--;
child = parent;
parent = hafftree[child].parent;
}
for (j = temp->start + 1; j < n; j++)
haffCode[i].bit[j] = temp->bit[j];
haffCode[i].start = temp->start;
haffCode[i].weight = temp->weight;
}
}
void preorder(HaffNode *hafftree,int n,int x,int y,int lenth)
{
if (hafftree[n].lchild != -1)
{
if (hafftree[hafftree[n].lchild].lchild == -1)
{
char te[2]; te[0] = hafftree[hafftree[n].lchild].character; te[1] = '\0';
draw(255, 0, 255, 1, x, y, lenth);
putText(image, te, Point(x - lenth, y + lenth), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 255, 255), 2, 8);
}
else
draw(255, 255, 0, 1, x, y,lenth);
imshow("tree", image);
waitKey(0);
}
if (hafftree[n].rchild != -1)
{
if (hafftree[hafftree[n].rchild].rchild == -1)
{
char te[2]; te[0] = hafftree[hafftree[n].rchild].character; te[1] = '\0';
draw(255, 0, 255, 0, x, y, lenth);
putText(image, te, Point(x + lenth, y + lenth), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 255, 255), 2, 8);
}
else
draw(255, 0, 0, 0, x, y,lenth);
imshow("tree", image);
waitKey(0);
}
if (hafftree[n].lchild != -1 || hafftree[n].rchild != -1)
{
lenth = lenth - 30;
}
if(hafftree[n].lchild!=-1)
preorder(hafftree, hafftree[n].lchild, x - lenth-30, y + lenth+30,lenth);
if(hafftree[n].rchild!=-1)
preorder(hafftree, hafftree[n].rchild, x + lenth +30, y + lenth+30,lenth);
}
void Compression(Code *haffcode, int n)
{
char c, character[100];
char tstr[20], code[30][10], str3[1000] = { 0 };
int ccount = 0;
int k = 0, i = 0, j = 0, count = 0;
int str[1000]; char instr[100];
int bit[7];
memset(str, -1, sizeof(int) * 1000);
FILE *fp1=fopen("C:\\Users\\chenh\\Desktop\\ctest\\Input.txt", "r");
FILE *fp2=fopen("C:\\Users\\chenh\\Desktop\\ctest\\Compression.txt", "w+");
FILE *fp3 = fopen("C:\\Users\\chenh\\Desktop\\ctest\\Codebook.txt", "r");
while (fscanf(fp3, "%c:\t%s\n", &c, tstr) != EOF)
{
character[ccount] = c;
strcpy(code[ccount++], tstr);
}
fgets(instr, 100, fp1);
for (i = 0; i < strlen(instr); i++)
{
for (j = 0; j < ccount; j++)
{
if (character[j] == instr[i])
{
strcat(str3, code[j]);
}
}
}
for (i = 0; i < strlen(str3); i++)
{
str[i] = str3[i] - '0';
printf("%d", str[i]);
}
count = i;
if(count%7!=0)
count = count + 7-count % 7;
for (j = i ; j < count; j++)
{
str[j] = 0;
}
for (i = 0; i < count; i+=7)
{
int t = 0;
for (j = i; j < i + 7; j++)
{
bit[t++] = str[j];
}
int sum = 0;
int exp = 6;
for (k = 0; k <7; k++)
{
sum = sum + bit[k]*pow(2, exp);
exp--;
}
printf("$%d", sum);
fprintf(fp2, "%c", sum);//多位空格分开
}
fclose(fp2);
}
void Translation()
{
char c,character[100];
char str[500], code[30][10], temp[10], str2[10], str3[1000] = { 0 };
int count = 0,k=0,kk=0;
FILE *fp1 = fopen("C:\\Users\\chenh\\Desktop\\ctest\\Codebook.txt", "r");
while (fscanf(fp1, "%c:\t%s\n", &c, str)!=EOF)
{
character[count] = c;
strcpy(code[count++], str);
}//读取密码本
fclose(fp1);
FILE *fp2 = fopen("C:\\Users\\chenh\\Desktop\\ctest\\Compression.txt", "r");
FILE *fp3 = fopen("C:\\Users\\chenh\\Desktop\\ctest\\Translation.txt", "w+");
fgets(str, 500, fp2);
printf("\n");
for (int i = 0; i < strlen(str); i++)
{
int num;
num = str[i] - ' ' + 32;
int p = 1, y = 0, yushu;
k = 0;
memset(str2, 0, sizeof(char) * 10);
while (1)
{
yushu = num % 2;
num /= 2;
str2[k++] =yushu+48;
if (num == 0)break;
}
for (int j = 6; j >= 0; j--)
{
if (str2[j] == '\0')str2[j] = '0';
str3[kk++] = str2[j];
printf("%c", str3[kk - 1]);
}
}
int flag = 0;
k = 0;
memset(temp, '\0', sizeof(temp));
for (int i = 0; i < strlen(str3); i++)
{
temp[k++] = str3[i];
for (int j = 0; j < count; j++)
{
if (strcmp(temp, code[j]) == 0)
{
flag = 1;
printf("%c", character[j]);
fprintf(fp3, "%c", character[j]);
break;
}
}
if (flag)
{
k = 0;
flag = 0;
memset(temp, '\0', sizeof(temp));
}
}
fclose(fp3);
}
void draw(int b, int g, int r, int flag, int x, int y,int lenth)
{
if (flag == 2)
{
circle(image, Point(x, y), 15, Scalar(b, g, r), -1);
imshow("tree", image);
}
else if (flag == 1)//zuoyi
{
line(image, Point(x, y), Point(x - lenth, y + lenth), Scalar(255,255,0), 4, CV_AA);
circle(image, Point(x - lenth, y + lenth), 15, Scalar(b, g, r), -1);
}
else//youyi
{
line(image, Point(x, y), Point(x + lenth, y + lenth), Scalar(255,255,0), 4, CV_AA);
circle(image, Point(x + lenth, y + lenth), 15, Scalar(b , g, r), -1);
}
}
哈夫曼编码,压缩,opencv画图
最新推荐文章于 2024-03-18 00:00:03 发布