【课设项目】 图像的边缘识别和处理问题 源码分享

先上效果图(原图/边缘识别 对比):

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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;
}

猜你喜欢

转载自blog.csdn.net/qq_45492531/article/details/105567709
今日推荐