用编程解决习题【计算机图像处理】

news2024/10/6 5:58:01

用编程解决习题【计算机图像处理】

  • 前言
  • 版权
    • 第三章 03采样量化与像素间关系
      • 三种距离计算
      • 编程
    • 第六章 06图像的直方图变换
      • 均衡化直方图
      • 编程
      • 规定化直方图
      • 编程
    • 第七章 07图像的噪声抑制
      • 均值滤波 中值滤波计算
      • 编程
      • knn滤波计算
      • 编程
    • 第十章 10二值图像的分析
      • 贴标签 膨胀 腐蚀
      • 编程
  • 最后

前言

2023-12-27 21:11:27

以下内容源自《【计算机图像处理】》
仅供学习交流使用

版权

禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://jsss-1.blog.csdn.net
禁止其他平台发布时删除以上此话

第三章 03采样量化与像素间关系

三种距离计算

一、请计算像素点a(0,1)和像素点b(6,9)之间的欧氏距离,棋盘距离以及城区距离。

欧氏距离:((6-0)^2+(9-1)^2)^0.5=10   345 6810勾股数
棋盘距离:max(|0-6|,|1-9|)=8
城区距离:(|0-6|+|1-9|)=14

编程

import java.util.Scanner;

/**
 * 第三章作业
 *
 * 2023-12-27 21:19:15
 *
 * 一、请计算像素点a(0,1)和像素点b(6,9)之间的欧氏距离,棋盘距离以及城区距离。
 *  欧氏距离:((6-0)^2+(9-1)^2)^0.5=10   345 6810勾股数
 *  棋盘距离:max(|0-6|,|1-9|)=8
 *  城区距离:(|0-6|+|1-9|)=14
 *
 *
 *
 */
public class Main3 {
    static class Point{
        int x;
        int y;

        public Point(){

        }

        public Point(int x,int y){
            this.x=x;
            this.y=y;
        }

        //欧式距离
        public static double distance1(Point p1,Point p2){
            return Math.sqrt(Math.pow(p1.x-p2.x,2)+Math.pow(p1.y-p2.y,2));
        }

        //棋盘距离
        public static double distance2(Point p1,Point p2){
            return Math.max(Math.abs(p1.x-p2.x),Math.abs(p1.y-p2.y));
        }

        //城区距离
        public static double distance3(Point p1,Point p2){
            return Math.abs(p1.x-p2.x)+Math.abs(p1.y-p2.y);
        }


    }


    public static Point p1;
    public static Point p2;

    //手动改值初始化
    public static void init(){
        p1=new Point(0,1);
        p2=new Point(6,9);
    }

    //自动输入初始化
    //0 1 6 9
    static void input() {
        Scanner scanner=new Scanner(System.in);
        int x1=scanner.nextInt();
        int y1=scanner.nextInt();
        int x2=scanner.nextInt();
        int y2=scanner.nextInt();
        p1=new Point(x1,y1);
        p2=new Point(x2,y2);
    }

    public static void main(String[] args) {
//        input(); //输入

        init();//手动改值
        System.out.println(Point.distance1(p1,p2));//10.0
        System.out.println(Point.distance2(p1,p2));//8.0
        System.out.println(Point.distance3(p1,p2));//14.0

    }




}



第六章 06图像的直方图变换

均衡化直方图

一幅灰度级为8的图像对应的归一化直方图为[0.17,0.25,0.21,0.16,0.07,0.08,0.04,0.02]。用列表法计算直方图均衡化后图像的灰度级和对应的概率,并画出处理前后直方图的对比图。

原始灰度级k01234567
原始直方图sk0.170.250.210.160.070.080.040.02
累计直方图tk0.170.420.630.790.860.940.981.0
扩展取整12456667
映射0->11->22->43->54->65->66->67->7
均衡化直方图0.170.250.210.160.190.02

编程

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main6 {

    //原始直方图
    static double[] sk;

    static int n;

    static int l;

    //累计直方图
    static double[] tk;

    //扩展取整
    static int [] extend;

    //均衡化后的直方图
    static double[] equalized;


    //手动改值初始化
    public static void init(){
        sk =new double[]{0.17,0.25,0.21,0.16,0.07,0.08,0.04,0.02};
        n= sk.length;
        l= n-1;
    }

    //自动输入初始化
    //8
    //0.17 0.25 0.21 0.16 0.07 0.08 0.04 0.02
    static void input() {
        Scanner scanner=new Scanner(System.in);
        //输入长度
        n= scanner.nextInt();
        l=n-1;
        sk =new double[n];
        int c=0;
        for (int i = 0; i < n; i++) {
            sk[c++]= scanner.nextDouble();
        }
    }

    public static void main(String[] args) {
//        input(); //输入


        init();//手动改值

        equalize();

    }

    //均衡化
    public static void equalize(){

        System.out.println("输出原始直方图:");
        System.out.println(Arrays.toString(sk));

        tk=new double[n];
        tk[0]=sk[0];

        for (int i = 1; i < n; i++) {
            tk[i]=tk[i-1]+sk[i];
        }

        System.out.println("输出累计直方图:");
        System.out.println(Arrays.toString(tk));

        extend=new int[n];
        for (int i = 0; i < n; i++) {
            extend[i]=(int)(tk[i]*l);
        }
        System.out.println("输出扩展取整:");
        System.out.println(Arrays.toString(extend));


        ArrayList<ArrayList<Integer>> map=new ArrayList<>();
        for (int i = 0; i < n; i++) {
            map.add(new ArrayList<>());
        }
        for (int i = 0; i < n; i++) {
            map.get(extend[i]).add(i);
        }

        System.out.println("输出映射关系:");
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> cur=map.get(i);
            if (!cur.isEmpty()){
                System.out.print(cur+"->"+i+"\t");
            }
        }
        System.out.println();


        equalized=new double[n];
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> cur=map.get(i);
            if (!cur.isEmpty()){
                for (Integer j : cur) {
                    equalized[i]+=sk[j];
                }
            }
        }

        System.out.println("输出均衡化的直方图:");
        System.out.println(Arrays.toString(equalized));

    }
}

输出原始直方图:
[0.17, 0.25, 0.21, 0.16, 0.07, 0.08, 0.04, 0.02]
输出累计直方图:
[0.17, 0.42000000000000004, 0.63, 0.79, 0.8600000000000001, 0.9400000000000001, 0.9800000000000001, 1.0]
输出扩展取整:
[1, 2, 4, 5, 6, 6, 6, 7]
输出映射关系:
[0]->1	[1]->2	[2]->4	[3]->5	[4, 5, 6]->6	[7]->7	
输出均衡化的直方图:
[0.0, 0.17, 0.25, 0.0, 0.21, 0.16, 0.19000000000000003, 0.02]


规定化直方图

请添加图片描述

请添加图片描述

编程

import java.util.Arrays;
import java.util.Scanner;

public class Main6_2 {

    //原始直方图
    static double[] sk;

    static int n;

    static int l;

    //累计直方图
    static double[] tk;

    //扩展取整
    static int [] extend;

    //均衡化后的直方图
    static double[] equalized;


    //手动改值初始化
    public static void init1(){
        sk =new double[]{0.19,0.25,0.21,0.16,0.08,0.06,0.03,0.02};
        n= sk.length;
        l= n-1;
    }

    //自动输入初始化
    /*
    8
    0.17 0.25 0.21 0.16 0.07 0.08 0.04 0.02
    */
    static void input1() {
        Scanner scanner=new Scanner(System.in);
        //输入长度
        n= scanner.nextInt();
        l=n-1;
        sk =new double[n];
        int c=0;
        for (int i = 0; i < n; i++) {
            sk[c++]= scanner.nextDouble();
        }
    }

    public static void init2(){
        sk =new double[]{0,0,0,0.2,0,0.6,0,0.2};
        n= sk.length;
        l= n-1;
    }

    /*
    8
    0 0 0 0.2 0 0.6 0 0.2
     */
    static void input2() {
        Scanner scanner=new Scanner(System.in);
        //输入长度
        n= scanner.nextInt();
        l=n-1;
        sk =new double[n];
        int c=0;
        for (int i = 0; i < n; i++) {
            sk[c++]= scanner.nextDouble();
        }
    }

    static double[] sk1;



    public static void main(String[] args) {

        double[] tk1 = op1();

        double[] tk2 = op2();

        sml(tk1,tk2);

        gml(tk1,tk2);

    }



    private static double[] op1() {
        //输入原始直方图
//        input1(); //输入
        init1();//手动改值

        sk1=new double[n];
        for (int i = 0; i < n; i++) {
            sk1[i]=sk[i];
        }

        System.out.println("原始直方图");
        System.out.println(Arrays.toString(sk1));

        step1();

        double[] tk1=new double[n];
        for (int i = 0; i < n; i++) {
            tk1[i]=tk[i];
        }
        System.out.println("原始累积直方图");
        System.out.println(Arrays.toString(tk1));

        record1=new int[n];
        for (int i = 0; i < n; i++) {
            record1[i]=record[i];
        }
        System.out.println("record1");
        System.out.println(Arrays.toString(record1));
        return tk1;
    }

    private static double[] op2() {
        //输入规定直方图
//        input1(); //输入
        init2();//手动改值

        System.out.println("规定直方图");
        System.out.println(Arrays.toString(sk));

        step1();

        double[] tk2=new double[n];
        for (int i = 0; i < n; i++) {
            tk2[i]=tk[i];
        }

        System.out.println("规定累积直方图");
        System.out.println(Arrays.toString(tk2));

        record2=new int[n];
        for (int i = 0; i < n; i++) {
            record2[i]=record[i];
        }
        System.out.println("record2");
        System.out.println(Arrays.toString(record2));
        return tk2;
    }

    //就是tk1距离tk2中的哪个最近,则tk1的下标对应tk2中的下标
    //因为都是非递减数列,所以使用双指针就好了,只是O(n)的复杂度

    //有个问题就是可能和原来的不对应,就是原来是0,加了前面的值才有值的
    //所以需要使用record来记录

    public static void sml(double[] tk1,double[] tk2){
        int[] map=new int[n];

        for (int i = 0,j=0 ; i <n; i++) {
            for (; j < n;j++ ) {
                if (j+1==n||Math.abs(tk1[i]-tk2[j])<Math.abs(tk1[i]-tk2[j+1])){
                    break;
                }
            }
            map[i]=record2[j];//不一定是j,而是j所前面的值
        }

        System.out.println("sml映射");
        System.out.println(Arrays.toString(map));

        double[] smled=new double[n];
        for (int i = 0; i < n; i++) {
            smled[map[i]]+=sk1[i];
        }

        System.out.println("变换后直方图");
        System.out.println(Arrays.toString(smled));



    }

    //tk2到tk1的距离
    //因为都是非递减数列,所以使用双指针就好了,只是O(n)的复杂度
    public static void gml(double[] tk1,double[] tk2){
        int[] map=new int[n];

        for (int i = 0,j=0 ; i <n; i++) {
            //跳过为0的或者和之前一样的
            if(tk2[i]==0||(i-1>=0&&tk2[i]==tk2[i-1])){
                continue;
            }
            //只要tk[i]到tk1[j]的距离一直递减就一直映射j->i
            for (; j < n;j++ ) {
                if (j-1<0||Math.abs(tk1[j]-tk2[i])<Math.abs(tk1[j-1]-tk2[i])){
                    map[j]=i;
                }else {
                    break;
                }
            }
        }

        System.out.println("gml映射");
        System.out.println(Arrays.toString(map));

        double[] gmled =new double[n];
        for (int i = 0; i < n; i++) {
            gmled[map[i]]+=sk1[i];
        }

        System.out.println("变换后直方图");
        System.out.println(Arrays.toString(gmled));


    }



    static int[] record;
    static int[] record1;
    static int[] record2;

    private static void step1() {
        record=new int[n];

        tk=new double[n];
        tk[0]=sk[0];

        record[0]=0;

        for (int i = 1; i < n; i++) {
            if(sk[i]==0){
                record[i]=record[i-1];
            }else {
                record[i]=i;
            }
            tk[i]=tk[i-1]+sk[i];
        }

    }



}

原始直方图
[0.19, 0.25, 0.21, 0.16, 0.08, 0.06, 0.03, 0.02]
原始累积直方图
[0.19, 0.44, 0.65, 0.81, 0.89, 0.95, 0.98, 1.0]
record1
[0, 1, 2, 3, 4, 5, 6, 7]
规定直方图
[0.0, 0.0, 0.0, 0.2, 0.0, 0.6, 0.0, 0.2]
规定累积直方图
[0.0, 0.0, 0.0, 0.2, 0.2, 0.8, 0.8, 1.0]
record2
[0, 0, 0, 3, 3, 5, 5, 7]
sml映射
[3, 3, 5, 5, 5, 7, 7, 7]
变换后直方图
[0.0, 0.0, 0.0, 0.44, 0.0, 0.45, 0.0, 0.11]
gml映射
[3, 5, 5, 5, 7, 7, 7, 7]
变换后直方图
[0.0, 0.0, 0.0, 0.19, 0.0, 0.62, 0.0, 0.19]

第七章 07图像的噪声抑制

均值滤波 中值滤波计算

此处注意,要点明凡是代替的点就是噪声点。
在这里插入图片描述
1.均值滤波
周围所有邻居的平均值
2.中值滤波
周围所有邻居的中位数
3.KNN滤波
周围和他差值最小的K个邻居的平均值

编程


import java.util.Arrays;
import java.util.Scanner;

/**
 *
 * 1、设原图像为
 * 4 4
 * 59 60 58 57
 * 61 90 59 57
 * 62 59 0  58
 * 56 61 60 56
 *
 *
 * 请对其进行均值滤波和中值滤波,并分析结果异同
 *
 *
 */

public class Main7 {

    static int[][] grid;

    static int n;
    static int m;

    //------------------------------------------------------------------------------------

    public static void init(){
        grid= new int[][]{
                {59, 60, 58, 57},
                {61, 90, 59, 57},
                {62, 59, 0, 58},
                {56, 61, 60, 56}
        };
        n= grid.length;
        m=grid[0].length;

    }

    /*
     4 4
     59 60 58 57
     61 90 59 57
     62 59 0  58
     56 61 60 56
     */
    public static void input(){
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        m=scanner.nextInt();
        grid=new int[n][m];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                grid[i][j]=scanner.nextInt();
            }
        }
    }

    //------------------------------------------------------------------------------------


    public static void main(String[] args) {
//        input(); //输入

        init();//手动改值


        System.out.println("输出原始图像");
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(grid[i]));
        }

        System.out.println("输出均值滤波图像");
        int[][] meanFiltered=meanFiltering();
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(meanFiltered[i]));
        }


        //输出中值滤波图像
        System.out.println("输出中值滤波图像");
        int[][] medianFiltered=medianFiltering();
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(medianFiltered[i]));
        }

    }
    
    //------------------------------------------------------------------------------------


    private static int[][] meanFiltering(){
        int[][] meanFiltered=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                meanFiltered[i][j]=grid[i][j];
            }
        }

        for (int i = 1; i < n-1; i++) {
            for (int j = 1; j < m-1; j++) {
                meanFiltered[i][j]=mean(i,j);
            }
        }


        return meanFiltered;
    }

    //返回(x,y)周围9个点的均值
    // 四舍五入
    private static int mean(int x, int y) {
        int sum=0;
        for (int i = x-1; i <= x+1; i++) {
            for (int j = y-1; j <= y+1; j++) {
                sum+=grid[i][j];
            }
        }
        return (int)(sum/9.0+0.5);
    }

    //------------------------------------------------------------------------------------

    private static int[][] medianFiltering() {
        int[][] medianFiltered=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                medianFiltered[i][j]=grid[i][j];
            }
        }

        for (int i = 1; i < n-1; i++) {
            for (int j = 1; j < m-1; j++) {
                medianFiltered[i][j]=median(i,j);
            }
        }
        return medianFiltered;
    }

    private static int median(int x, int y) {
        int[] arr=new int[9];
        int c=0;
        for (int i = x-1; i <= x+1; i++) {
            for (int j = y-1; j <= y+1; j++) {
                arr[c++]=grid[i][j];
            }
        }
        Arrays.sort(arr);
        int m=(9+1)/2;
        return arr[m];
    }
    
}



输出原始图像
[59, 60, 58, 57]
[61, 90, 59, 57]
[62, 59, 0, 58]
[56, 61, 60, 56]
输出均值滤波图像
[59, 60, 58, 57]
[61, 56, 55, 57]
[62, 56, 56, 58]
[56, 61, 60, 56]
输出中值滤波图像
[59, 60, 58, 57]
[61, 60, 59, 57]
[62, 61, 59, 58]
[56, 61, 60, 56]


knn滤波计算

此处注意,要点明凡是代替的点就是噪声点。
在这里插入图片描述
1.均值滤波
周围所有邻居的平均值
2.中值滤波
周围所有邻居的中位数
3.KNN滤波
周围和他差值最小的K个邻居的平均值

编程

/**
 *  2、对下图进行KNN平滑滤波,并由结果指出图中的噪声点。
 *
 *     1 5 255 100 200 200
 *     1 7 254 101 10 9
 *     3 7 10 100 2 6
 *     1 0 8 7 2 1
 *     1 1 6 50 2 2
 *     2 3 9 7 2 0
 */

import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main7_2 {
    static int[][] grid;

    static int n;
    static int m;

    static int k=5;

    //------------------------------------------------------------------------------------

    public static void init(){
        grid= new int[][]{
                {1, 5, 255, 100, 200, 200},
                {1, 7, 254, 101, 10, 9},
                {3, 7, 10, 100, 2, 6},
                {1, 0, 8, 7, 2, 1},
                {1, 1, 6, 50, 2, 2},
                {2, 3, 9, 7, 2, 0}
        };
        n= grid.length;
        m=grid[0].length;

    }

    /*
    6 6
    1 5 255 100 200 200
    1 7 254 101 10 9
    3 7 10 100 2 6
    1 0 8 7 2 1
    1 1 6 50 2 2
    2 3 9 7 2 0
     */
    public static void input(){
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        m=scanner.nextInt();
        grid=new int[n][m];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                grid[i][j]=scanner.nextInt();
            }
        }
    }

    public static void main(String[] args) {
//        input(); //输入

        init();//手动改值


        System.out.println("输出原始图像");
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(grid[i]));
        }

        System.out.println("输出knn滤波图像");
        int[][] knnFiltered=knnFiltering();
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(knnFiltered[i]));
        }


        noise(knnFiltered);

    }

    private static void noise(int[][] knnFiltered) {
        System.out.println("输出是否为噪声点");
        int[][] isNoisePoint=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if(grid[i][j]!= knnFiltered[i][j]){
                    isNoisePoint[i][j]=1;
                }
            }
        }

        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(isNoisePoint[i]));
        }

        System.out.println("噪声点坐标");
        ArrayList<int[]> noisePoints=new ArrayList<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if(isNoisePoint[i][j]==1){
                    noisePoints.add(new int[]{i,j});
                }
            }
        }
        for (int[] noise:noisePoints) {
            System.out.print("("+noise[0]+","+noise[1]+")\t");
        }
        System.out.println();
    }

    private static int[][] knnFiltering() {
        int[][] knnFiltered=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                knnFiltered[i][j]=grid[i][j];
            }
        }

        for (int i = 1; i < n-1; i++) {
            for (int j = 1; j < m-1; j++) {
                knnFiltered[i][j]=knn(i,j);
            }
        }
        return knnFiltered;

    }

    private static int knn(int x, int y) {

        //优先队列:差值 和 本身的值
        PriorityQueue<int[]> queue=new PriorityQueue<>((a,b)->a[0]-b[0]);
        //按差值排列

        for (int i = x-1; i <= x+1; i++) {
            for (int j = y-1; j <= y+1; j++) {
                queue.add(new int[]{Math.abs(grid[i][j]-grid[x][y]),grid[i][j]});
            }
        }


        int sum=0;
        for (int i = 0; i < k; i++) {
            sum+=queue.poll()[1];
        }
        return (int)(1.0*sum/k+0.5);

    }

}


输出原始图像
[1, 5, 255, 100, 200, 200]
[1, 7, 254, 101, 10, 9]
[3, 7, 10, 100, 2, 6]
[1, 0, 8, 7, 2, 1]
[1, 1, 6, 50, 2, 2]
[2, 3, 9, 7, 2, 0]
输出knn滤波图像
[1, 5, 255, 100, 200, 200]
[1, 6, 162, 64, 25, 9]
[3, 7, 8, 46, 4, 6]
[1, 1, 8, 7, 2, 1]
[1, 1, 7, 16, 2, 2]
[2, 3, 9, 7, 2, 0]
输出是否为噪声点
[0, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 1, 0]
[0, 0, 1, 1, 1, 0]
[0, 1, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0]
[0, 0, 0, 0, 0, 0]
噪声点坐标
(1,1)	(1,2)	(1,3)	(1,4)	(2,2)	(2,3)	(2,4)	(3,1)	(4,2)	(4,3)	

第十章 10二值图像的分析

贴标签 膨胀 腐蚀

在这里插入图片描述

1)

原始图像
1 1 1 0 0 0
1 0 0 1 0 1
1 0 0 0 0 1
0 0 1 0 1 1
0 1 0 0 1 0
0 0 0 1 0 0

添标签
1 1 1 0 0 0
1 0 0 1 0 2
1 0 0 0 0 2
0 0 3 0 2 2
0 3 0 0 2 0
0 0 0 2 0 0

2)

原始图像
1 1 1 0 0 0
1 0 0 1 0 1
1 0 0 0 0 1
0 0 1 0 1 1
0 1 0 0 1 0
0 0 0 1 0 0


腐蚀
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0


膨胀
1 1 1 1 1 0
1 0 0 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 1 1 1 1 0
0 0 0 1 0 0

编程

import java.util.Arrays;
import java.util.Scanner;

/**
 *
 * 设一个二值图像为
     1 1 1 0 0 0
     1 0 0 1 0 1
     1 0 0 0 0 1
     0 0 1 0 1 1
     0 1 0 0 1 0
     0 0 0 1 0 0
 * 1)在8连通意义下,对该图贴标签
 * 2)对上图分别进行一次腐蚀和膨胀运算,结构元素为S=[[1,0],[1,1]]
 * 结构元素原点在S的 (1,1) 坐标处




 */

public class Main8 {

    static int[][] grid;

    static int n;
    static int m;

    static int k=2;
    static int[][] s=new int[][]{
            {1,0},
            {1,1}
    };

    //------------------------------------------------------------------------------------

    public static void init(){
        grid= new int[][]{
                {1, 1, 1, 0, 0, 0},
                {1, 0, 0, 1, 0, 1},
                {1, 0, 0, 0, 0, 1},
                {0, 0, 1, 0, 1, 1},
                {0, 1, 0, 0, 1, 0},
                {0, 0, 0, 1, 0, 0}
        };
        n= grid.length;
        m=grid[0].length;

    }

    /*
     6 6
     1 1 1 0 0 0
     1 0 0 1 0 1
     1 0 0 0 0 1
     0 0 1 0 1 1
     0 1 0 0 1 0
     0 0 0 1 0 0
     */
    public static void input(){
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        m=scanner.nextInt();
        grid=new int[n][m];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                grid[i][j]=scanner.nextInt();
            }
        }
    }

    //------------------------------------------------------------------------------------


    public static void main(String[] args) {
//        input(); //输入

        init();//手动改值


        System.out.println("输出原始图像");
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(grid[i]));
        }

        int[][] label=labeling();
        System.out.println("输出标签图像");
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(label[i]));
        }


        int[][] corrosion=corrode();
        System.out.println("输出腐蚀图像");
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(corrosion[i]));
        }

        int[][] expansion=expand();
        System.out.println("输出膨胀图像");
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(expansion[i]));
        }



    }

    static boolean[][] visited;
    static int labelCount=1;

//    /*
    //8邻域
    static int[][] step=new int[][]{
            {-1,-1},{-1,0},{-1,1},
            {0,-1},{0,1},
            {1,-1},{1,0},{1,1}
    };


    static int stepN=8;
//     */

    /*
    //4邻域
    static int[][] step=new int[][]{
           {-1,0}, {0,-1}, {0,1}, {1,0}
    };

    static int stepN=4;
     */


    private static int[][] labeling() {
        int[][] label=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                label[i][j]=grid[i][j];
            }
        }

        visited=new boolean[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j]==1){
                    if (!visited[i][j]){
                        dfs(i,j,label);
                        labelCount++;
                    }
                }
            }
        }

        return label;

    }

    private static void dfs(int x, int y,int[][] label) {
        visited[x][y]=true;
        label[x][y]=labelCount;
        for (int i = 0; i < stepN; i++) {
            int nextX=x+step[i][0];
            int nextY=y+step[i][1];
            if(nextX>=0&&nextX<n&&nextY>=0&&nextY<m){
                if (grid[nextX][nextY]==1){
                    if (!visited[nextX][nextY]){
                        dfs(nextX,nextY,label);
                    }
                }
            }
        }
    }


    //------------------------------------------------------------------------------------

    //求腐蚀图像
    private static int[][] corrode(){
        int[][] corrosion=new int[n][m];

        for (int i = 0; i < n-1; i++) {
            for (int j = 0; j < m-1; j++) {
                if (grid[i][j]==1){
                    corrosion[i][j]=co(i,j);
                }
            }
        }

        return corrosion;
    }



    //腐蚀操作
    private static int co(int x, int y) {
        //是否被腐蚀
        int flag=1;
        for (int i = 0; i < k; i++) {
            for (int j = 0; j < k; j++) {
                if(s[i][j]==1){
                    if (grid[x+i][y+j]!=1){
                        flag=0;
                        break;
                    }
                }
            }
            if (flag==0){
                break;
            }
        }
        return flag;
    }

    //------------------------------------------------------------------------------------

    //求膨胀图像
    private static int[][] expand() {
        int[][] expansion=new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                expansion[i][j]=grid[i][j];
            }
        }

        for (int i = 0; i < n-1; i++) {
            for (int j = 0; j < m-1; j++) {
                if (grid[i][j]==0){
                    expansion[i][j]=ex(i,j);
                }
            }
        }
        return expansion;
    }

    //膨胀操作
    private static int ex(int x, int y) {
        //是否被膨胀
        int flag=0;
        for (int i = 0; i < k; i++) {
            for (int j = 0; j < k; j++) {
                if(s[i][j]==1){
                    if (grid[x+i][y+j]==1){
                        flag=1;
                        break;
                    }
                }
            }
            if (flag==1){
                break;
            }
        }
        return flag;
    }

}


输出原始图像
[1, 1, 1, 0, 0, 0]
[1, 0, 0, 1, 0, 1]
[1, 0, 0, 0, 0, 1]
[0, 0, 1, 0, 1, 1]
[0, 1, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 0]
输出标签图像
[1, 1, 1, 0, 0, 0]
[1, 0, 0, 1, 0, 2]
[1, 0, 0, 0, 0, 2]
[0, 0, 3, 0, 2, 2]
[0, 3, 0, 0, 2, 0]
[0, 0, 0, 2, 0, 0]
输出腐蚀图像
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
输出膨胀图像
[1, 1, 1, 1, 1, 0]
[1, 0, 0, 1, 1, 1]
[1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1]
[0, 1, 1, 1, 1, 0]
[0, 0, 0, 1, 0, 0]

4邻域下的贴标签

输出原始图像
[1, 1, 1, 0, 0, 0]
[1, 0, 0, 1, 0, 1]
[1, 0, 0, 0, 0, 1]
[0, 0, 1, 0, 1, 1]
[0, 1, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 0]
输出标签图像
[1, 1, 1, 0, 0, 0]
[1, 0, 0, 2, 0, 3]
[1, 0, 0, 0, 0, 3]
[0, 0, 4, 0, 3, 3]
[0, 5, 0, 0, 3, 0]
[0, 0, 0, 6, 0, 0]

最后

2023-12-28 10:36:51

我们都有光明的未来

祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1339479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络隔离后,怎样建立高效安全的数据安全交换通道?

数据安全对企业生存发展有着举足轻重的影响&#xff0c;数据资产的外泄、破坏都会导致企业无可挽回的经济损失和核心竞争力缺失。数据流动才能让其释放价值&#xff0c;想要保护企业核心资产&#xff0c;就要实现数据安全交换。 很多企业为了防止知识产权、商业机密数据泄露&am…

python嵌套异常处理器

1 python嵌套异常处理器 python的异常处理器支持嵌套。 1.1 嵌套的try/except处理器 用法 def f1():raise E def f2():try:f1()except E:pass try:f2() except E:pass描述 嵌套的try/except处理器&#xff0c;发生异常时&#xff0c;控制权会跳回具有相符的except分句、最近…

钉钉机器人接入定时器(钉钉API+XXL-JOB)

钉钉机器人接入定时器&#xff08;钉钉APIXXL-JOB&#xff09; 首先需要创建钉钉内部群 在群设置中找到机器人选项 选择“自定义”机器人 通过Webhook接入自定义服务 创建完成后会生成一个send URL和一个加签码 下面就是干货 代码部分了 DingDingUtil.sendMessageByText(webho…

相机内参标定理论篇------相机模型选择

相机种类&#xff1a; 当拿到一款需要标定内参的相机时&#xff0c;第一个问题就是选择那种的相机模型。工程上相机类型的划分并不是十分严格&#xff0c;一般来说根据相机FOV可以把相机大概分为以下几类&#xff1a; 长焦相机&#xff1a;< 标准相机&#xff1a;~&…

gin框架使用系列之六——自定义中间件

系列目录 《gin框架使用系列之一——快速启动和url分组》《gin框架使用系列之二——uri占位符和占位符变量的获取》《gin框架使用系列之三——获取表单数据》《gin框架使用系列之四——json和protobuf的渲染》《gin框架使用系列之五——表单校验》 一、gin中间件概述 gin中将…

开源项目推荐:Frooodle/Stirling-PDF

简介一个本地的处理 PDF 的工具&#xff0c;界面是 Web UI&#xff0c;可以支持 Docker 部署。各种主要的 PDF 操作都可以支持。比如拆分、合并、转换格式、重新排列、添加图片、旋转、压缩等等。这个本地托管的网络应用最初完全由 ChatGPT 制作&#xff0c;后来逐渐发展&#…

数据结构学习 Leetcode322 零钱兑换

关键词&#xff1a;动态规划 完全背包 记忆化搜索 一个套路&#xff1a; 01背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要逆序遍历完全背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要正序遍历 题目&#xff1a; 方法一&#xff…

【Docker-Dev】Mac M2 搭建docker mysql

Mac M2 搭建Mysql 1、前言2、前置说明-Docker的代理访问3、前置说明-Mysql的镜像访问3.1、提取信息3.1.1、开启Mysql的实例3.1.2、Dokcer连接Mysql3.1.3、官方简易版的docker-compose3.1.4、如何登录mysql bash3.1.5、自定义my.cnf文件3.1.6、如何知道其他自定义配置项 4、M2安…

【算法题】矩阵顺时针旋转90° (js)

力扣链接&#xff1a;https://leetcode.cn/problems/rotate-matrix-lcci/description/ 本人题解&#xff1a; /*** param {number[][]} matrix* return {void} Do not return anything, modify matrix in-place instead.*/ var rotate function (matrix) {const x matrix.le…

[SWPUCTF 2021 新生赛]finalrce

[SWPUCTF 2021 新生赛]finalrce wp 注&#xff1a;本文参考了 NSSCTF Leaderchen 师傅的题解&#xff0c;并修补了其中些许不足。 此外&#xff0c;参考了 命令执行(RCE)面对各种过滤&#xff0c;骚姿势绕过总结 题目代码&#xff1a; <?php highlight_file(__FILE__); …

【算法】运用滑动窗口方法解决算法题(C++)

文章目录 1. 滑动窗口 介绍2. 滑动窗口算法引入209.长度最小的子数组 3. 使用滑动窗口解决算法题3.无重复字符的最长子串1004.最大连续1的个数III1658.将x减到0的最小操作数904.水果成篮LCR015.找到字符串中所有字母异位词30.串联所有单词的子串76.最小覆盖子串 1. 滑动窗口 介…

在Vue2中快速使用ECharts

在Vue2中快速使用ECharts ECharts这里简单介绍一下ECharts的图表其他图表 背景: 因为博主在做项目时&#xff0c;有一个需求要求是可视化渲染出文章的分类信息以及文章内容&#xff0c;当时第一时间就想到了ECharts&#xff0c;因此就引入了在Vue2中快速使用ECharts。 ECharts …

详细讲解Java使用EasyExcel函数来操作Excel表(附实战)

目录 前言1. EasyExcel类2. 原理分析3. demo4. 实战 前言 前阵时间好奇下载Excel&#xff0c;特意学习实战了该功能&#xff1a;详细讲解Java使用HSSFWorkbook函数导出Excel表&#xff08;附实战&#xff09; 现在发觉还有个EasyExcel也可专门用来读写Excel表 1. EasyExcel类…

张驰咨询:如何战胜实施精益生产培训的常见难题?

精益生产又称作“Lean Manufacturing”或“Lean Production”&#xff0c;它是一种强调消除生产过程中一切形式的浪费&#xff0c;注重流程优化以提升整体效能的管理哲学。源自丰田生产系统&#xff08;Toyota Production System&#xff09;&#xff0c;精益生产培训目标在于最…

MyBatis分页机制深度解析

前言 在企业项目的数据库操作中&#xff0c;分页查询是一个常见需求&#xff0c;尤其当数据量庞大时。MyBatis 作为 我们Java 开发者的持久层框架&#xff0c;为分页提供了灵活的支持。 本篇文章我们将深入探讨 MyBatis 的分页机制&#xff0c;使我们在实际开发项目中运用自如…

【C++高阶(九)】C++类型转换以及IO流

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; C高阶 1. 前言2. C语言类型转换的方式3. C的强制…

Flask登陆后登陆状态及密码的修改和处理

web/templates/common 是统一布局 登录成功 后flask框架服务器默认由login.html进入仪表盘页面index.html(/),该页面的设置在 (web/controllers/user/index.py)&#xff0c;如果想在 该仪表盘页面 将 用户信息 展示出来&#xff0c;就得想办法先获取到 当前用户的 登陆状态。…

11、基于LunarLander登陆器的A2C强化学习(含PYTHON工程)

11、基于LunarLander登陆器的A2C强化学习&#xff08;含PYTHON工程&#xff09; LunarLander复现&#xff1a; 07、基于LunarLander登陆器的DQN强化学习案例&#xff08;含PYTHON工程&#xff09; 08、基于LunarLander登陆器的DDQN强化学习&#xff08;含PYTHON工程&#xff…

thinkcmf 文件包含 x1.6.0-x2.2.3 已亲自复现

thinkcmf 文件包含 x1.6.0-x2.2.3 CVE-2019-16278 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 ThinkCMF是一款基于PHPMYSQL开发的中文内容管理框架&#xff0c;底层采用ThinkPHP3.2.3构建。ThinkCMF提出灵活的应用机制&a…

Elasticsearch中复制一个索引数据到新的索引中

问题 我有时候&#xff0c;需要调试一个已经存在的ES索引&#xff0c;需要从已有的索引复制数据到新的索引中去。 解决 这里我借助一个GUI工具&#xff0c;来解决这个问题&#xff0c;底层它是使用Reindex的API实现索引数据复制的。利用Reindex API搞不定这个事情&#xff0…