先上效果图(原图/边缘识别 对比): |
1、系统概述:
日常需求中,不难发现有很多图像描边的功能要求,以及图像平滑、降噪等优化需求。这时候,将一个图像数据化处理的技术就显得格外重要。通过对图像对应的矩阵信息进行梯度操作、阈值处理、边缘化保留和卷积,可以将一个个点阵转化为平滑的的图像点,实现图像到数据,再从数据到图像的转化。
系统主要功能分四类:一个功能是图像数据采集,通过读取包含图像信息的txt文件,转化为矩阵,存入数组中,本程序提供四个复杂图像供用户选择。第二个功能是梯度处理与阈值判断,用户可以将自己选择的图像进行梯度处理,先分别得到横向梯度和纵向梯度,得到综合梯度,并借此得到整个图像的阈值,改阈值用于后续判断边缘。第三个功能是边缘化处理和边的存储,先将将矩阵进行01化处理,大于阈值的为1,即为边缘,小于阈值的为0。然后利用01化处理后的新矩阵进行图像输出,并且同一边缘染上了同一颜色,便于用户观察。由于图像显示出来会有噪点产生(即没有用的边缘),这是因为原图像矩阵本身存在这样的噪点,为了解决这个问题,第三个功能还附带了边缘保留的技术,利用边缘化处理时存好的边,进行排序,按照边缘宽度从小到大剔除不需要的边缘,而保留的边缘数量由用户交互决定,使得程序更加人性化。第四个功能是卷积平滑,导入卷积矩阵,进行卷积平滑处理,初始卷积矩阵为中间为-7,其他为1的矩阵,可以产生中心锐化,边缘模糊的效果。
2.功能需求描述:
(1)功能介绍模块:是一个初始界面,用于介绍本程序包含的所有功能模块,以及本次执行的功能,在每一次功能完成及下一个功能开始时会出现。
(2)菜单模块:本模块是图像采集前,和用户交互输入用户喜欢的图像的功能。本菜单模块提供4个复杂图像, 分别是1.哆啦A梦2.初音3.皮卡丘4.海绵宝宝。编号对应图像编号,用户输出对应的编号即可进行该图像的图像数据采集操作。
(3)图像数据采集及显示模块:本模块的功能是将用户前一步选择的图像进行数据采集,将该图像的信息以矩阵形式存入数组中,并显示给用户,同时用户可在目录中找到该图像的矩阵信息。
(4)梯度处理及阈值判断模块:本模块是图像处理的第一步,先通过矩阵中的行列信息得到行梯度和列梯度,并借此生成综合梯度,再利用综合梯度判断阈值,阈值用于后续判断边缘。
(5)边缘处理+生成+降噪模块:本模块是本程序的核心代码,也是功能最强大的一块。首先利用前一步得到的阈值,将图像矩阵进行01化处理,1是比阈值大的点,0是比阈值小的点。因为比阈值大的就是边缘,所以后续操作都是对1的操作。接着对01矩阵进行边缘存储和染色,存储时,将一个边缘中选取一个点作为代表(因为只要得到边缘内一个点通过八连通的dfs可以得到边缘内的其他点),记录该边缘的深度(或者说宽度),存入结构体中。染色是利用前面得到的边缘,将同一边缘染上同一颜色,便于用户观察。 然后将边缘生成给用户。 降噪是用户交互输入需要保留的边缘数量,程序将边缘宽度从小到大去除,使得噪点大大减少。
(6)卷积平滑模块:利用本地的卷积矩阵,将图像进行平滑处理,使得图像主体边缘模糊而主体本身突出。用户可通过修改卷积矩阵.txt文件达到不一样的平滑效果。
流程图如下:
图像数据文件放评论区~
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <fstream>
#include <cstdlib>
#include <conio.h>
#include <algorithm>
#include <time.h>
#include <windows.h>
#include<stdlib.h>
#define clean system("cls")
#define maxn 1000
using namespace std;
typedef vector<vector<int> > mat; //重命名二维数组
void color(short x) //自定义函根据参数改变颜色
{
if (x >= 0 && x <= 15)//参数在0-15的范围颜色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一个参数,改变字体颜色
else//默认的颜色白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
typedef struct level //梯度信息
{
int horizontal;
int vertical;
int sum;
} L;
typedef struct Pos //用边缘里的一个点代表一个边缘
{
int begin_x;
int begin_y;
int depth;
} P;
P Edge_pos[maxn*5];
bool cmp(P a, P b) //按照边缘宽度(即深度)排序
{
return a.depth < b.depth;
}
L** Matrix_leval(int row, int col, mat& Matrix) //返回一个L型的二维数组,每个元素包含水平和竖直梯度
{
L** ans = (L**)malloc(row * sizeof(L*)); //申请动态空间
for (int i = 0; i < row; i++) //计算梯度
{
ans[i] = (L*)malloc(sizeof(L) * col);
for (int j = 0; j < col; j++)
{
if (i == row - 1)
{
ans[i][j].horizontal = 0;
}
else ans[i][j].horizontal = abs(Matrix[i][j] - Matrix[i + 1][j]); //水平方向
if (j == col - 1)
{
ans[i][j].vertical = 0;
}
else ans[i][j].vertical = abs(Matrix[i][j] - Matrix[i][j + 1]); //竖直方向
ans[i][j].sum = ans[i][j].horizontal + ans[i][j].vertical;
}
}
return ans; //返回地址
}
void show(mat& Matrix, L**& ans, int row, int col) //显示矩阵梯度
{
ans = Matrix_leval(row, col, Matrix); //先计算
color(9);
printf(" ===========按任意键查看矩阵行列梯度以(x,y)形式表示,其中x表示行梯度,y表示列梯度:~ ☆★.°·∴°☆\n");
printf(" ===========矩阵较大,生成过程大约在10秒左右,请耐心等待~ (先显示1/4矩阵)☆★.°·∴°☆\n");
system("pause");
color(15);
for (int i = 0; i < row / 2; i++) //再输出
{
for (int j = 0; j < col / 2; j++)
{
printf("(%d,%d)", ans[i][j].horizontal, ans[i][j].vertical);
}
cout << endl;
}
color(14);
printf("\n\n~ ☆★.°·∴°☆~ ☆★.°·∴°☆任意键查看综合梯度(数据量较大,先显示1/4矩阵)!!!~ ☆★.°·∴°☆~ ☆★.°·∴°☆\n\n");
cout << endl;
cout << endl;
cout << endl;
printf(" \n");
system("pause");
printf("~ ☆★.°·∴°☆~ ☆★.°·∴°☆综合梯度为:。~ ☆★.°·∴°☆~ ☆★.°·∴°☆\n\n");
color(15);
for (int i = 0; i < row / 2; i++)
{
for (int j = 0; j < col / 2; j++)
{
printf("(%d)", ans[i][j].sum);
}
cout << endl;
}
}
int calculate_threshold(L** ans, int row, int col) //计算阈值
{
int res = 0;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
res += ans[i][j].sum;
return res / (row * col);
}
vector<pair<int, int> > pos_for_Edge; //该数组用来存边缘集合
int vis[maxn][maxn]; //vis数组,代表当前结点是否访问过
int dir[8][2] = { {-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1} }; //方向数组,表示八连通方向,上下左右、左上右上、 左下右下
int depth = 0;
void DFS_for_Edge(L** Matrix, int x, int y, mat& Edge, int threshold, int row, int col)
{
if (x >= row || y >= col || x < 0 || y < 0 || vis[x][y] || Matrix[x][y].sum <= threshold) return;
Edge[x][y] = 1;
vis[x][y] = 1;
depth++;
for (int i = 0; i < 8; i++)
DFS_for_Edge(Matrix, x + dir[i][0], y + dir[i][1], Edge, threshold, row, col);
}
int vis1[maxn][maxn]; //vis数组用来标记当前位置是否走过
void DFS_for_recover(mat& Edge, int row, int col, int x, int y) //用来保留m条边,其他的复原,即是上面的逆运算
{
if (x >= row || y >= col || x < 0 || y < 0 || vis1[x][y] || !Edge[x][y]) return;
vis1[x][y] = 1;
Edge[x][y] = 0;
for (int i = 0; i < 8; i++)
DFS_for_recover(Edge, row, col, x + dir[i][0], y + dir[i][1]);
}
void with_begin() //用户开始界面
{
color(9);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(11);
cout << " -------------------------------------" << endl;
cout << " |*********欢迎来到二次元的图像处理所(请全屏使用!!!~~~~~)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " |*****图像处理(介绍):********|" << endl;
cout << " |*** →☆图像参数获取 ********|" << endl;
cout << " |***** ☆图像梯度处理+阈值判断********|" << endl;
cout << " |***** ☆设置边缘+边缘处理********|" << endl;
cout << " |***** ☆平滑操作*******|" << endl;
cout << " |***********************************|" << endl;
cout << " |*******(按任意键进入图像参数获取操作)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(9);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(20);
cout << endl;
system("pause");
clean;
}
void put_in() //用户界面2, 输入编号来进行对应图像处理
{
color(6);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
//printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(15);
cout << " -------------------------------------" << endl;
cout << " |~~~~~~中二所图片选择中心(以下为图像及编号)~~~~~~|" << endl;
cout << " |*********************************** |" << endl;
cout << " |°°°°°°°1:多啦A梦°°°°° |" << endl;
cout << " |°°°°°°°2:初音未来°°°°° |" << endl;
cout << " |°°°°°°°3:皮卡丘°°°°°° |" << endl;
cout << " |°°°°°°°4:海绵宝宝°° °°°|" << endl;
cout << " |***********************************|" << endl;
cout << " |*******(请输入你想处理的图像编号)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(6);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(20);
cout << endl;
cout << " (图像编号:) ";
}
int hash_map[1000][1000]; //map同vis数组,标记
int color_map[1000][1000]; //用来标记当前位置的color颜色
void DFS_for_color(mat& Edge, int row, int col, int flag, int chosen, int x, int y) //给边缘染色的函数功能, 对一个边缘内的点进行DFS搜索,染上同一种颜色,方便用户查看
{
if (flag) //01化处理后的Edge矩阵,对当前为1的点判断
{
if (x >= row || y >= col || x < 0 || y < 0 || hash_map[x][y] || Edge[x][y] == 0)
{
return;
}
}
else //反之亦然
{
if (x >= row || y >= col || x < 0 || y < 0 || hash_map[x][y] || Edge[x][y] == 1)
{
return;
}
}
hash_map[x][y] = 1; //标记
color_map[x][y] = chosen;
for (int i = 0; i < 8; i++) //八连通深搜
DFS_for_color(Edge, row, col, flag, chosen, x + dir[i][0], y + dir[i][1]);
}
void show_for_Matrix(mat Matrix, int row, int col) //展示矩阵
{
color(6);
printf("\n\n\n\n\n\n\n\n");
printf(" **********************************************************************************\n");
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
color(9);
// cout<<" -------------------------------------"<<endl;
printf(" -----------------------------------------------------------------------------\n");
printf(" | |\n");
printf(" | |\n");
printf(" | |\n");
printf(" | |\n");
printf(" | 图像已数据已采集完毕 |\n");
printf(" | |\n");
printf(" | |\n");
printf(" | (!!!由于图像矩阵较大,查看时请耐心等待矩阵加载!!!!) |\n");
printf(" | |\n");
printf(" | |\n");
printf(" | 了解后按任意键查看参数矩阵 |\n");
printf(" --------------------------------------------------------------------------\n");
color(6);
printf(" ------------------------------------- ---------------------------------------\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(15);
system("pause");
printf(" \n\n\n ===========矩阵较大,生成过程大约在10秒左右,请耐心等待~ (先显示1/4矩阵)☆★.°·∴°☆\n");
for (int i = 0; i < row / 2; i++)
{
for (int j = 0; j < col / 2; j++)
printf("%d ", Matrix[i][j]);
cout << endl;
}
}
void show_for_second() //第二部分衔接窗口
{
color(9);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(11);
cout << " -------------------------------------" << endl;
cout << " |*********欢迎来到二次元的图像处理所**********|" << endl;
cout << " |***********************************|" << endl;
cout << " |*****图像处理(介绍):********|" << endl;
cout << " |***** ★图像参数获取 ********|" << endl;
cout << " |***** → ☆图像梯度处理+阈值判断********|" << endl;
cout << " |***** ☆设置边缘+边缘处理********|" << endl;
cout << " |***** ☆平滑操作*******|" << endl;
cout << " |***********************************|" << endl;
cout << " |*******(按任意键进入下一个窗口)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(9);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(20);
cout << endl;
system("pause");
clean;
}
void show_for_threshold(L** ans, int row, int col, int& threshold) //梯度显示窗口
{
threshold = calculate_threshold(ans, row, col);
color(6);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
//printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(15);
cout << " -------------------------------------" << endl;
cout << " |~~~~~~中二所图片阈值中心~~~~~~|" << endl;
cout << " |*********************************** |" << endl;
cout << " |°°°°°°°阈°°°°° °|" << endl;
cout << " |°°°°°°°值°°°°° °|" << endl;
cout << " |°°°°°°°查°°°°° °|" << endl;
cout << " |°°°°°°°询°°°°° °|" << endl;
cout << " |***********************************|" << endl;
printf(" |*******(阈值大小为:%d)**********|\n", threshold);
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(6);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(15);
}
void show_for_third() //第三界面衔接窗口
{
color(9);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(11);
cout << " -------------------------------------" << endl;
cout << " |*********欢迎来到二次元的图像处理所**********|" << endl;
cout << " |***********************************|" << endl;
cout << " |*****图像处理(介绍):********|" << endl;
cout << " |***** ★图像参数获取 ********|" << endl;
cout << " |***** ★图像梯度处理+阈值判断********|" << endl;
cout << " |***** →☆设置边缘+边缘处理********|" << endl;
cout << " |***** ☆平滑操作*******|" << endl;
cout << " |***********************************|" << endl;
cout << " |*******(按任意键进行边缘处理操作,本程序将同一边缘染上同样颜色,方便用户观察)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(9);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(20);
cout << endl;
system("pause");
clean;
}
void show_for_forth() //第四界面衔接窗口
{
color(9);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(11);
cout << " -------------------------------------" << endl;
cout << " |*********欢迎来到二次元的图像处理所**********|" << endl;
cout << " |***********************************|" << endl;
cout << " |*****图像处理(介绍):********|" << endl;
cout << " |***** ★图像参数获取 ********|" << endl;
cout << " |***** ★图像梯度处理+阈值判断********|" << endl;
cout << " |***** ★设置边缘+边缘处理********|" << endl;
cout << " |***** → ☆平滑操作*******|" << endl;
cout << " |***********************************|" << endl;
cout << " |*******(按任意键进行平滑操作)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(9);
printf(" **********************************************************************************\n");
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(20);
cout << endl;
system("pause");
clean;
}
void show_for_ending() //最后的界面
{
color(9);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(11);
cout << " -------------------------------------" << endl;
cout << " |*********欢迎光顾二次元的图像处理所**********|" << endl;
cout << " |***********************************|" << endl;
cout << " |*****图像处理(介绍):********|" << endl;
cout << " |***** ★图像参数获取 ********|" << endl;
cout << " |***** ★图像梯度处理+阈值判断********|" << endl;
cout << " |***** ★设置边缘+边缘处理********|" << endl;
cout << " |***** ★平滑操作*******|" << endl;
cout << " |***********************************|" << endl;
cout << " |*******(您已完成所有图像处理流程,感谢使用~~!请按任意键退出程序)**********|" << endl;
cout << " |***********************************|" << endl;
cout << " -------------------------------------" << endl;
color(9);
printf(" **********************************************************************************\n");
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(20);
cout << endl;
system("pause");
//clean;
}
void solve_for_last(mat fold, L** ans, int row, int col, int curx, int cury, L**& tmp) //卷积处理,平滑操作
{
int posx = 0;
int posy = 0;
for (int i = 0; i < row; i++) //先初始化
for (int j = 0; j < col; j++)
tmp[i][j].sum = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (j + cury <= col && i + curx <= row) //卷积得到新的梯度
{
for (int k = i; k < i + curx; k++)
{
for (int l = j; l < j + cury; l++)
tmp[i][j].sum += fold[k - i][l - j] * ans[i][j].sum;
}
}
}
}
}
int main()
{
//1.生成矩阵====
with_begin();
put_in();
L** ans; //ans用来存梯度
L** tmp;
srand(time(0));
mat Matrix(800, vector<int>(800, 0)); //Matrix矩阵导入图像参数
int row = 800, col = 800;
char s[5000];
char ch = getchar();
int pos1 = 0;
color(3);
cout << endl;
cout << endl;
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
color(6);
// printf(" ===========PS:图片矩阵较大,以下显示矩阵时会产生较长输出,属于正常现象,请耐心等待输出完毕!!~ ☆★.°·∴°☆\n");
color(15);
printf(" ~~~~~~~~~~~~~~~~~~~~~请按任意键采集图片参数矩阵~~~~~~~~~~·~~~ \n");
system("pause");
FILE* fp;
switch (ch) //按照需求读入文件
{
case '1':
{
fp = fopen("哆啦A梦.txt", "r");
int pos2 = 0;
int col2 = 0;
while (fgets(s, 800, fp) != NULL) //采集图片中信息,将图片信息转化成数字
{
col = strlen(s); //cout<<col<<endl;
int sum = 0;
for (int i = 0; i < col; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
sum *= 10;
sum += s[i] - '0';
if (i == col - 1 || s[i + 1] == '\n')
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
if ((s[i] < '0' || s[i]>'9') && i != col - 1)
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
pos1++;
pos2 = 0;
}
fclose(fp);
row = pos1;
col = col2;
break;
}
case '2':
{
fp = fopen("初音.txt", "r");
int pos2 = 0;
int col2 = 0;
while (fgets(s, 1000, fp) != NULL) //采集图片中信息,将图片信息转化成数字
{
col = strlen(s); //cout<<col<<endl;
int sum = 0;
for (int i = 0; i < col; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
sum *= 10;
sum += s[i] - '0';
if (i == col - 1 || s[i + 1] == '\n')
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
if ((s[i] < '0' || s[i]>'9') && i != col - 1)
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
pos1++;
pos2 = 0;
}
fclose(fp);
row = pos1;
col = col2;
break;
}
case '3':
{
fp = fopen("皮卡丘.txt", "r");
int pos2 = 0;
int col2 = 0;
while (fgets(s, 600, fp) != NULL) //采集图片中信息,将图片信息转化成数字
{
col = strlen(s); //cout<<col<<endl;
int sum = 0;
for (int i = 0; i < col; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
sum *= 10;
sum += s[i] - '0';
if (i == col - 1 || s[i + 1] == '\n')
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
if ((s[i] < '0' || s[i]>'9') && i != col - 1)
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
pos1++;
pos2 = 0;
}
fclose(fp);
row = pos1;
col = col2;
break;
}
case '4':
{
fp = fopen("海绵宝宝.txt", "r");
int pos2 = 0;
int col2 = 0;
while (fgets(s, 600, fp) != NULL) //采集图片中信息,将图片信息转化成数字
{
col = strlen(s);
int sum = 0;
for (int i = 0; i < col; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
sum *= 10;
sum += s[i] - '0';
if (i == col - 1 || s[i + 1] == '\n')
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
if ((s[i] < '0' || s[i]>'9') && i != col - 1)
{
Matrix[pos1][pos2++] = sum;
col2 = max(col2, pos2);
sum = 0;
}
}
pos1++;
pos2 = 0;
}
fclose(fp);
row = pos1;
col = col2;
break;
}
}
show_for_Matrix(Matrix, row, col);
color(6);
printf(" ~~~~~~~~~~~~~~~~~~~~~请按任意键,进入下一个窗口,进行梯度处理操作~~~~~~~~~~·~~~ \n");
show_for_second();
//2.处理梯度与阈值===
printf(" ===========以下为梯度矩阵~ ☆★.°·∴°☆\n");
color(15);
show(Matrix, ans, row, col); //梯度矩阵显示函数
tmp = Matrix_leval(row, col, Matrix);
int threshold;
show_for_threshold(ans, row, col, threshold);
//3.生成边缘矩阵====
show_for_third();
mat Edge(row + 2, vector<int>(col + 2, 0));
memset(vis, 0, sizeof(vis));
memset(vis1, 0, sizeof(vis1));
int pos = 0;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
int temp = vis[i][j];
depth = 0;
DFS_for_Edge(ans, i, j, Edge, threshold, row, col); //对边缘进行01化处理,处理完后点为1的就是边缘
if (vis[i][j] == !temp)
{
Edge_pos[pos].begin_x = i; //同时存边
Edge_pos[pos].begin_y = j;
Edge_pos[pos++].depth = depth;
}
}
printf(" ====边缘图像为:====\n");
memset(hash_map, 0, sizeof(hash_map));
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
int chosen = rand() % 15 + 1; //先对同一边缘染同样色
DFS_for_color(Edge, row, col, Edge[i][j], chosen, i, j);
}
}
for (int i = 0; i < row; i++) //处理完输出 , 这是第一步操作后的结果, 未平滑,未降噪
{
for (int j = 0; j < col; j++)
{
if (Edge[i][j] == 1) color(color_map[i][j]), printf("#");
else color(color_map[i][j]), printf(" ");
}
cout << endl;
}
color(6);
printf(" **********************************************************************************\n");
//color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
//printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
color(15);
cout << " -------------------------------------" << endl;
cout << " |~~~~~~中二所边缘处理中心(请你为图像保留适当边缘)~~~~~~|" << endl;
cout << " |*********************************** |" << endl;
cout << " |°°°°°°°边°°°°° |" << endl;
cout << " |°°°°°°°缘°°°°° |" << endl;
cout << " |°°°°°°°保°°°°° |" << endl;
cout << " |°°°°°°°留°° °°°|" << endl;
cout << " |***********************************|" << endl;
printf(" |*******(当前含有的边缘数量为%d)**********|\n", pos);
color(3);
printf(" |********请输入你要保留的边缘条数m,其中m<=%d|\n", pos);
color(15);
printf(" |********PS:适当清除边缘有助于去除图像噪点~~~~~\n");
cout << " -------------------------------------" << endl;
color(6);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
int m;
printf(" 保留的边缘数量为:");
cin >> m;
printf(" ====新的边缘图像为:====\n");
sort(Edge_pos, Edge_pos + pos, cmp); //按边长(即边缘宽度)进行排序
for (int i = 0; i < pos - m; i++) //去掉不需要的点
DFS_for_recover(Edge, row, col, Edge_pos[i].begin_x, Edge_pos[i].begin_y);
memset(hash_map, 0, sizeof(hash_map));
for (int i = 0; i < row; i++) //处理颜色渐变
{
for (int j = 0; j < col; j++)
{
int chosen = rand() % 16;
DFS_for_color(Edge, row, col, Edge[i][j], chosen, i, j);
}
}
for (int i = 0; i < row; i++) //处理完输出
{
for (int j = 0; j < col; j++)
{
if (Edge[i][j] == 1) color(color_map[i][j]), printf("%c", rand() % 26 + 'a');
else color(color_map[i][j]), printf("`");
}
cout << endl;
}
color(3);
cout << endl;
cout << endl;
cout << endl;
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆本次清除了%d个噪点!!! ~~~ \n", pos - m);
show_for_forth();
mat fold(10, vector<int>(10, 0));
fp = fopen("卷积矩阵.txt", "r");
int curx = 0;
int cury = 0;
int maxy = 0;
while (fgets(s, 60, fp) != NULL) //读入卷积矩阵
{
int len = strlen(s);
int f = 1;
for (int i = 0; i < len; i++)
{
if (s[i] >= '0' && s[i] <= '9')
fold[curx][cury++] = (s[i] - '0') * f, f = 1;
else if (s[i] == '-') f = -1;
}
curx++;
maxy = cury;
cury = 0;
}
color(14);
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°导入的卷积矩阵为:~~~ ∴° ☆..·★.°·∴°☆★.°·∴°☆ \n");
color(3);
for (int i = 0; i < curx; i++) //输出卷积矩阵
{
for (int j = 0; j < maxy; j++)
printf("%d ", fold[i][j]);
cout << endl;
}
cout << endl;
cout << endl;
cout << endl;
cout << endl;
cout << endl;
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°按任意键进行图像平滑操作并得到处理后的得到的矩阵综合梯度∴° ☆..·★.°·∴°☆★.°·∴°☆ \n");
system("pause");
solve_for_last(fold, ans, row, col, curx, maxy, tmp); //最后界面
threshold = calculate_threshold(tmp, row, col); //得到平滑后的新梯度,新矩阵
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆ \n");
/* for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
printf("%d ",tmp[i][j].sum);
cout<<endl;
}*/
color(3);
color(15);
cout << " -------------------------------------" << endl;
cout << " |~~~~~~中二所平滑处理中心(按任意键得到最终平滑图像)~~~~~~|" << endl;
cout << " |*********************************** |" << endl;
cout << " |°°°°°°°最°°°°° |" << endl;
cout << " |°°°°°°°终°°°°° |" << endl;
cout << " |°°°°°°°图°°°°° |" << endl;
cout << " |°°°°°°°像°° °°°|" << endl;
cout << " |***********************************|" << endl;
printf(" |*******(已进行卷积处理)**********|\n");
color(15);
printf(" |***************~~~~~~~~~~~~~~~~\n");
cout << " -------------------------------------" << endl;
color(6);
printf(" **********************************************************************************\n");
// color();
printf(" °★.☆° .★·°∴°★.°·∴°☆ ·°∴° ☆..·★.°·∴°☆★.°·∴°☆\n");
printf(" ☆°★°∴°°∴ ☆°.·★°∴°.★.°·∴°☆★.°·∴°☆★.°·∴°☆∴°☆\n");
system("pause");
color(15);
mat Edge1(row + 2, vector<int>(col + 2, 0));
memset(vis, 0, sizeof(vis));
memset(vis1, 0, sizeof(vis1));
pos = 0;
for (int i = 0; i < row; i++) //下面对平滑后的矩阵的阈值处理、边缘处理同上
for (int j = 0; j < col; j++)
{
int temp = vis[i][j];
depth = 0;
DFS_for_Edge(tmp, i, j, Edge1, threshold, row, col); //对边缘进行01化处理
if (vis[i][j] == !temp)
{
Edge_pos[pos].begin_x = i;
Edge_pos[pos].begin_y = j;
Edge_pos[pos++].depth = depth;
}
}
sort(Edge_pos, Edge_pos + pos, cmp);
for (int i = 0; i < pos - m; i++)
DFS_for_recover(Edge1, row, col, Edge_pos[i].begin_x, Edge_pos[i].begin_y);
memset(hash_map, 0, sizeof(hash_map));
for (int i = 0; i < row; i++) //处理完输出
{
for (int j = 0; j < col; j++)
{
int chosen = rand() % 15 + 1;
DFS_for_color(Edge1, row, col, Edge1[i][j], chosen, i, j);
}
}
for (int i = 0; i < row; i++) //处理完输出
{
for (int j = 0; j < col; j++)
{
if (Edge1[i][j] == 1) color(color_map[i][j]), printf("%c", rand() % 26 + 'a');
else color(color_map[i][j]), printf("`");
}
cout << endl;
}
show_for_ending();
return 0;
}