当前位置:网站首页>21天学习挑战赛--图像物体的边界
21天学习挑战赛--图像物体的边界
2022-08-10 05:36:00 【yeah_you_are】
活动地址:CSDN21天学习挑战赛
题目描述
给一个二维数组M行N列,数组中的数字代表图片的像素,为了简化问题,仅包含像素1和5两种像素,每种像素代表一个物体,将两个不同物体相邻的格子称为边界,求像素1代表的边界个数。(0<M<100,0<<100)
其中像素1代表的物体边界是指像素为1并且与像素5相邻的格子,而相邻的概念是指八个方向(上、下、左、右、左上、左下、右上、右下)的相近。
如上图,其中黄色部分即为边界,根据相邻的概念,黄色的格子组成了两个边界。
上图中的黄色格子据相邻的概念只有一个边界。
输入示例
6 6
1 1 1 1 1 1
1 5 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 5
输出
2
解析见上图
思考
解决这个问题可以分为两步:
确定边界格子
判断边界格子所属边界的个数
那么就有了解决问题的思路,第一步确定边界格子,可以将5周围的格子标记出来,这里是数组,那就赋一个不是1、5的值就好了,这里用2标记,于是我们有了:
2 2 2 1 1 1
2 5 2 1 1 1
2 2 2 1 1 1
1 1 1 1 1 1
1 1 1 1 2 2
1 1 1 1 2 5
这样所有的边界格子被标记出来了,然后第二步判断边界格子所属边界,那么就是找2的格子,找到一个2的格子a便立即根据相邻规律将所有与格子a相邻的所有为2的格子变为3,那么找到2的次数便是边界的个数。
3 3 3 1 1 1
3 5 3 1 1 1
3 3 3 1 1 1
1 1 1 1 1 1
1 1 1 1 3 3
1 1 1 1 3 5
代码
根据上面的思考,里面都有一个给相邻格子赋值的操作,先抽象成方法。
/**给相邻的格子赋值,pixel为当前值,target为目标值,只有当前值为pixel才会有赋值操作 *i,j分别对应数组中中心点的位置 *recursion确定是否为递归 */
public void put(int i, int j, int[][] array, int pixel, int target, boolean recursion) {
//遍历上、中、下
for (int a=-1;a<=1;a++){
//遍历左、中、右
for (int b=-1;b<=1;b++) {
//确保数组下标不越界,并且数组当前位置的值为指定像素值pixel
if (i+a < array.length && i+a >= 0 &&
j+b < array[0].length && j+b >= 0 &&
array[i+a][j+b] == pixel) {
array[i+a][j+b] = target;
//递归
if (recursion) {
put(i+a,j+b, array, pixel, target, true);
}
}
}
}
}
此处定义的方法 put() 主要功能是将数组当前位置的所有相邻部分并且其像素pixel为指定值的格子赋上目标值target,当递归recursion为true时,会将根据相邻规则画出的一个块都赋上目标值。
第二步,判断边界个数,用上面的方法递归计算边界的个数。
public static void main(String[] args) {
//初始化数组
int[][] a = new int[6][6];
for (int i=0;i<a.length;i++) {
for (int j=0;j<a[0].length;j++){
a[i][j] = 1;
}
}
a[1][1] = 5;
a[5][5] = 5;
//标记像素5的边界,用2标记
for (int i=0;i<a.length;i++) {
for (int j=0;j<a[0].length;j++){
if (a[i][j] == 5)
//调用put方法标记边界
put(i,j,a,1,2,false);
}
}
//统计边界个数
int count = 0;
for (int i=0;i<a.length;i++) {
for (int j=0;j<a[0].length;j++){
//找到2的格子,并递归标记
if (a[i][j] == 2) {
put(i, j, a, 2, 3, true);
count ++;
}
}
}
System.out.println("边界个数:" + count);
}
其实这里还可以尝试用不同的值标记不同的边界,那么也许更明显,但是在尝试过程中,一定要避免2、1之类的已经出现的值,可能让递归陷入死循环,会报栈溢出错误。
至此,问题解决。
边栏推荐
猜你喜欢
随机推荐
pytorch-07.处理多维特征的输入
每日刷题(day02)——leetcode 622. 设计循环队列
Unity中实现Animation Clip动画片段的倒播(该案例可以防止动画延迟)
钴镍回收树脂的工艺原理
pytorch-05.用pytorch实现线性回归
Convolutional Neural Network (CNN) for mnist handwritten digit recognition
.Net Core imports tens of millions of data to Mysql
Notes for RNN
51单片机室内环境甲醛PM2.5光照温度湿度检测及窗帘加湿消毒控制系统
【烘焙】肉松蛋糕卷
Explain the principle of MySql index in detail
【简易笔记】PyTorch官方教程简易笔记 EP4
Linux的文件IO与标准IO,以及IO缓存
C#对MySQL数据库进行增删改查操作(该操作还有防止MySQL注入功能)
R语言聚类分析——代码解析
系统架构和问题定位
STM32F407ZG TIM通用定时器
酸阻滞树脂
LeetCode 1351. Counting Negative Numbers in Ordered Matrices (Simple)
Notes for RNN and Decision Tree









