题目信息
图像的形态学是图像处理中可以化为一个单独的分支,主要是由数学的集合论中的相关理论发展而来,用于处理灰度图像与二值化图像中的重要手段。
开运算(Open):图像形态学重要的操作之一,是基于膨胀和腐蚀操作组合而成。主要应用在二值图像中,灰度图像亦可。过程:开运算=先腐蚀+后膨胀 输入图像+结构元素。
输入
输入格式如样例输入所示。
第一行为两个由空格分开的奇数N和M,分别代表进行开运算时使用的矩形结构元的高和宽。
(注:矩形结构元的原点为矩形中心,且结构元内的所有元素均为1)
例如,N=3,M=3表示如下结构元:
1 1 1
1 1 1
1 1 1
第二行为两个由空格分开的数字H和W,分别代表待处理的二值灰度图片的高和宽,并满足H>N, W>M。
接下来H行,每行有W个数字,每个数字代表图片相应位置的灰度值,灰度值的取值为0或者255,相邻的数字由空格隔开。
读取数据时要求以行优先的方式读取。
输出
图片的开运算结果,由H行、W列数字组成。
每一行中的数字用空格隔开,并且行的末尾没有空格符。
测试样例
3 3
7 6
255 255 0 0 0 255
0 255 255 255 255 0
0 255 255 255 255 255
0 255 255 255 255 0
0 255 255 255 0 0
255 255 255 255 255 255
0 0 0 0 0 255
0 0 0 0 0 0
0 255 255 255 255 0
0 255 255 255 255 0
0 255 255 255 255 0
0 255 255 255 0 0
0 255 255 255 0 0
0 0 0 0 0 0
解答
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//freopen("/Users/zhj/Downloads/text.txt", "r", stdin);
int N, M, H, W;
cin >> N >> M >> H >> W;
int N_side = (N - 1) / 2;
int M_side = (M - 1) / 2;
vector<vector<int>> src;
vector<vector<bool>> flag;
for (int i = 0; i < H; i++)
{
vector<int> line;
vector<bool> bool_line;
for (int j = 0; j < W; j++)
{
int tmp;
cin >> tmp;
line.push_back(tmp);
bool_line.push_back(false);
}
src.push_back(line);
flag.push_back(bool_line);
}
//腐蚀
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (src[i][j] == 255)
{
bool op = false;
for (int p = i - N_side; p <= i + N_side; p++)
{
for (int q = j - M_side; q <= j + M_side; q++)
{
if (p >= 0 && p < H && q >= 0 && q < W)
{
if (src[p][q] == 0)
{//出现0
op = true;
}
}
}
}
if (op)
{//出现0
flag[i][j] = true;
}
}
}
}
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (flag[i][j])
{
src[i][j] = 0;
flag[i][j] = false;
}
}
}
//膨胀
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (src[i][j] == 0)
{
bool op = false;
for (int p = i - N_side; p <= i + N_side; p++)
{
for (int q = j - M_side; q <= j + M_side; q++)
{
if (p >= 0 && p < H && q >= 0 && q < W)
{
if (src[p][q] == 255)
{//出现255
op = true;
}
}
}
}
if (op)
{//出现255
flag[i][j] = true;
}
}
}
}
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (flag[i][j])
{
src[i][j] = 255;
}
}
}
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
cout << src[i][j];
if (j < W - 1)
{
cout << " ";
}
}
cout << endl;
}
return 0;
}