当前位置:网站首页>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之类的已经出现的值,可能让递归陷入死循环,会报栈溢出错误。
至此,问题解决。
边栏推荐
猜你喜欢

Test of the opposite sex what you look like?

pytorch-11. Convolutional Neural Network (Advanced)

以STM32F103C6T6为例通过配置CubeMX实现EXIT外部中断

Unity中实现Animation Clip动画片段的倒播(该案例可以防止动画延迟)

LeetCode 938.二叉搜索树的范围和(简单)

LeetCode 2011.执行操作后的变量值(简单)

在Unity中利用代码动态更改场景中的天空盒

Notes for RNN

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)

LeetCode 162.寻找峰值(中等)
随机推荐
LeetCode 1351.统计有序矩阵中的负数(简单)
ASP.NET有关于文件上传、下载、全选、删除选中重要干货(亲测有效)
STM32单片机手机APP蓝牙高亮RGB彩灯控制板任意颜色亮度调光
51单片机营养液自动配置搅拌系统TDS浓度采集自动加水加营养液
ASP.NET连接SQL Server的步骤
【fiddler2】使用fiddler mock response 数据
51单片机BH1750智能补光灯台灯光强光照恒流源LED控制系统
STM32F407ZG PWM
51单片机教室人数进出统计检测数码管显示装置红外传感器
【简易笔记】PyTorch官方教程简易笔记 EP4
pytorch-08.加载数据集
【图像识别】训练一个最最简单的AI使其识别Vtuber
Common class String overview
LeetCode 2011. Variable Value After Action (Simple)
二维卷积定理的验证(下,cv2.filter2D())
【简易笔记】PyTorch官方教程简易笔记 EP3
Machine Learning - Clustering - Shopping Mall Customer Clustering
深度学习阶段性报告(一)
在Unity中利用代码动态更改场景中的天空盒
手机端应用类型