前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java 线程与多线程

Java 线程与多线程

作者头像
Mirror王宇阳
发布于 2020-11-12 03:23:35
发布于 2020-11-12 03:23:35
1.9K00
代码可运行
举报
运行总次数:0
代码可运行

Java是一门支持多线程的编程语言!

什么是进程?

计算机中内存、处理器、IO等资源操作都要为进程进行服务。

一个进程上可以创建多个线程,线程比进程更快的处理单元,而且所占用的资源也小,多线程的应用也是性能最高的。


Java的多线程实现:(三种方式)

  在Java中实现多线程有两种途径:

    1、继承Thread类

    2、实现Runnable接口

    3、实现Callable接口

继承Thread类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyThread extends Thread {  //继承Thread 即 多线程类【线程操作主类】
    
}

ps:在Java中,任何一个类继承了Thread类,都视为该类为多线程类。

在Java程序中都有一个“起点”即开始的地方;那么多线程类也有一个“起点”——run()方法,也就是说在多线程的每个主体类中都必须要覆写Thread类中所提供的run()方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void run() ;

run()方法没有提供参数和返回值,那么也就表示了线程一旦开始就要一直执行,不能够返回内容。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import sun.security.mscapi.KeyStore.MY;

class MyThread extends Thread {  //继承Thread 即 多线程类
    private String name ;
    public MyThread(String name) {
        this.name = name ;
    }
    @Override
    public void run () {
        for (int x = 0 ; x < 200 ; x ++) {
            System.out.println(this.name + "--->" + x);            
        } //线程类执行的功能就是循环的输出操作
    }
}
public class TestDemo {

    public static void main(String[] args) {
        MyThread mt1 = new MyThread("A >>>") ;
        MyThread mt2 = new MyThread("B >>>") ; 
        MyThread mt3 = new MyThread("C >>>") ;
        
        mt1.run();  // 未真正意义的启动多线程
        mt2.run();
        mt3.run();
    }

}

多线程的启动方法:Start()方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void start() ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 启动start()方法
public class TestDemo {

    public static void main(String[] args) {
        MyThread mt1 = new MyThread("A >>>") ;
        MyThread mt2 = new MyThread("B >>>") ; 
        MyThread mt3 = new MyThread("C >>>") ;
        
        mt1.start();
        mt2.start();
        mt3.start();
    }

}

真正的多线程,会交替的抢占资源执行程序。

上例程序的功能就是多线程输出,而a,b,c三个抢占资源执行自己的功能

为什么多线程的启用调用的不是run()而是必须调用start() ???

——————————————————————————————————

实现Runnable接口:(为了规避单继承局限问题)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@FunctionalInterface // 函数式接口
public interface Runnable {
    public void run() ;
}

【函数式接口的特点:一个接口只有一个方法】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import sun.security.mscapi.KeyStore.MY;

class MyThread implements Runnable {  //实现 Runnable  即 多线程继承
    private String name ;
    public MyThread(String name) {
        this.name = name ;
    }
    @Override
    public void run () {
        for (int x = 0 ; x < 200 ; x ++) {
            System.out.println(this.name + "--->" + x);            
        } //线程类执行的功能就是循环的输出操作
    }
}
public class TestDemo {

    public static void main(String[] args) {
        MyThread mt1 = new MyThread("A >>>") ;
        MyThread mt2 = new MyThread("B >>>") ; 
        MyThread mt3 = new MyThread("C >>>") ;
        // 由于Runnable接口没有定义start方法,而一定的规定要求,必须通过Thread。start方法来启动继承;
        // Thread类中有 【Thread(Runnable target)】构造方法,可以接收Runnable接口的参数
        // 于是我们可以实例化Threda类,将Runnable对象交给Thread类处理并start()方法启动多线程
        new Thread(mt1).start();
        new Thread(mt2).start();
        new Thread(mt3).start();
    }

}

#由此介绍了Thread和Runnable两种实现多线程的方法!

两者之间的实现方式:

  使用Runnable接口与Thread类相比之下,解决了Thrad类单继承局限的问题;

数据共享的不同

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 class MyThread extends Thread {  
 2     private int tick = 10 ;
 3     @Override
 4     public void run() {
 5         for (int x = 0 ; x < 100 ; x ++) {
 6             if (this.tick > 0) {
 7                 System.out.println(this.tick --);                
 8             }            
 9         }
10     }
11 }
12 public class TestDemo {
13 
14     public static void main(String[] args) {
15         MyThread mt1 = new MyThread() ;
16         MyThread mt2 = new MyThread() ; 
17         MyThread mt3 = new MyThread() ;
18         // 由于mythread继承了thread类,所以类中继承了start()方法
19         mt1.start();
20         mt2.start();
21         mt3.start();
22     }
23 
24 }

上例代码是通过继承Thread类实现的多线程操作,本例的目的在于表达,我们只有10元;例子中的15~17行声明了三个不同的对象,产生了三个不同内存,相互的数据是独立的;如果按照19~21行代码start()方法启动线程,结果就是10出现三次,因为三个对象的数据是独立的。

运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
10
9
8
7
6
5
4
3
2
1
10
9
8
7
6
5
4
3
2
1
10
9
8
7
6
5
4
3
2
1
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 class MyThread implements Runnable {  
 2     private int tick = 10 ;
 3     @Override
 4     public void run() {
 5         for (int x = 0 ; x < 100 ; x ++) {
 6             if (this.tick > 0) {
 7                 System.out.println(this.tick --);                
 8             }            
 9         }
10     }
11 }
12 public class TestDemo {
13 
14     public static void main(String[] args) {
15         // 在Runnable多线程下,只需要实例化一个MyThread对象
16         MyThread mt = new MyThread() ;
17         // 实例化Threda类,将Runnable对象交给Thread类处理并start()方法启动多线程
18         // 通过实例化Thread使用start()方法来实现三个(多)线程,且造作的数据对象都是同一个
19         new Thread(mt).start();
20         new Thread(mt).start();
21         new Thread(mt).start();
22     }
23 
24 }

19~21行代码显示,我们将唯一的MyThread对象 “mt” 作为Runnable对象传给Thread的构造方法。

运行结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
10
7
6
5
4
8
2
1
9
3

两个程序例子,都是实现三个线程的启动;不同的地方在于,Thread的三个线程使用的是三个不同的实例对象,而Runnable的三个线程均是通过实例化Thread类调用Start()方法对同一实例对象进行三个线程的操作。Runnable更好的实现了同一数据共享(当然Thread也可以,只是没有Runnable简单)

# 两者的区别

  Thread类是Runnable接口的一个子类,使用Runnable接口实现多线程可以避免单继承的局限性

  Runnable接口实现的多线程可以比Thrad类实现的多线程更加清楚的描述

Callable接口:

  Runnable接口实现的多线程不能返回操作结果;所以提供了一个新的多线程接口——Callable接口【java.util.concurrent 包】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@FunctionalInterface
public interface Callable<V> {  // 函数式接口
    public V call() ;
}

call()方法在 执行主要功能后,可以返回结果,而返回结果的类型有Calable接口泛型来决定。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 import java.util.concurrent.Callable;
 2 import java.util.concurrent.ExecutionException;
 3 import java.util.concurrent.FutureTask;
 4 
 5 class MyThread implements Callable<String> {   //实现Callable接口,并定义泛型为String
 6     private int tick = 10 ;
 7     public String run() {
 8         for (int x = 0 ; x < 100 ; x ++) {
 9             if (this.tick > 0) {
10                 System.out.println(this.tick --);                
11             }            
12         }
13         return "stop" ;
14     }
15     @Override
16     public String call() throws Exception {
17         // TODO Auto-generated method stub
18         return null;
19     }
20 }
21 public class TestDemo {
22 
23     public static void main(String[] args) throws Exception {
24         /* 
25          * Thread类中并没有接收Callabel对象的构造方法,所以无法通过start()来启动多线程
26          * 但是Java提供java.util.concurrent。FutureTask<V> 类 , 
27          * 在FutureTask类的定义结构如下:
28          *         public class FutureTask<V> extends Object implements Future<V> , Runnable
29          *     类中有如下的构造方法:
30          *         public FutureTask(Callable<V> callable)
31          * FutureTask类接收Callable接口对象。目的就是:取得call()方法的返回结果
32          */
33         MyThread mt1 = new MyThread();
34         MyThread mt2 = new MyThread();
35         FutureTask<String> task1 = new FutureTask<String>(mt1); // 目的是为了接收call返回值
36         FutureTask<String> task2 = new FutureTask<String>(mt2);
37         // FutureTask是Runnable接口子类,所以可以使用Thread类的构造来接收task对象
38         new Thread(task1).start();
39         new Thread(task2).start();
40         // 多线程执行完毕后,依靠FutureTask的父接口 Future中的get()方法完成。
41         System.out.println("A--->" + task1.get());
42         System.out.println("B--->" + task2.get());
43         
44     }
45 
46 }

多线程的常用操作方法:

1、线程的命名与取得:

  所有线程的执行,每一次都是不同的结果;如果要想区分线程就要依靠线程的名字;对于线程的命名,一般会在启动之前定义。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
构造方法:    public Thread(Runnable target , String name) ;
设置命名:    public final void setName(String name) ;  // final 方法不可被覆写
取得命名:    public final String getName() ;

上述的三个方法,是Thread类中的方法,主要实现的就是线程的命名和取得操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyThread implements Runnable {   
    /*
     * 对于线程的命名,setName() getName() 等方法都在Thread类中
     * 如果在实现Runnable接口的线程中,这个类就不会继承Thread类,无法实现Thread的命名操作方法
     * 如果要取得名字和命名,能够取得的只有当前本方法的线程名【public static Thread currentThread()】
     * currentThread()方法取得是当前线程的Thread对象,所以取得Thread对象后,就可以直接调用Thread中的方法,
     * 并且,currentThread()是定义为 Static属性,不需要实例,可以直接类方法调用。
     */
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()); 
        // 取得当前run线程对象,并调用getName()
    }
}
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread() ;
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
    }

}

上例代码并没有设置线程名字,只是简单实现了getName()方法和CurrentThread()方法;当然如果我们没有给线程命名而调用方法的话!系统给自动的给线程赋名(会给线程编号命名):【运行结果】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Thread-1
Thread-2
Thread-0

设置线程名:(实例化Thread启动Start前命名)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread() ;
        new Thread(mt,"线程 = A").start();
        new Thread(mt,"线程 = B").start();
        new Thread(mt,"线程 = C").start();
    }

}

运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
线程 = A
线程 = C
线程 = B

#mian()主线程的存在

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread() ;
        new Thread(mt,"线程 ").start();

        mt.run(); // 直接调用run()方法
    }

}

运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
main
线程 

因为run()中输出的是当前线程对象的名(取得当前对象,调用getName方法输出线程对象名);综合分析得知:main主方法也是一个线程,【mian线程】那么所有在主方法上创建的线程都可以表示为子线程;而我们都是在主线程下创建子线程。

每当使用Java命令去解释一个程序类的时候,对于操作系统而言,都相当于启动了一个进程上的一个子线程。

JVM启动:

  main线程:程序的主要执行,以及启动子线程

  GC线程:负责垃圾收集

2、休眠

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 import java.util.concurrent.Callable;
 2 import java.util.concurrent.ExecutionException;
 3 import java.util.concurrent.FutureTask;
 4 
 5 class MyThread implements Runnable {   
 6     @Override
 7     public void run() {
 8 
 9         for ( int x = 0 ; x < 10000 ; x ++ ) {
10             try { // 执行sleep休眠,休眠1秒(sleep是以纳秒为单位)
11                 Thread.sleep(1000);
12             } catch (InterruptedException e) {
13                 e.printStackTrace();
14             }
15             System.out.println(Thread.currentThread().getName() + ">>>" + x);
16         }
17     }
18 }
19 public class TestDemo {
20 
21     public static void main(String[] args) throws Exception {
22         MyThread mt = new MyThread() ;
23         new Thread(mt,"线程 A").start();
24     }
25 
26 }

3、线程的优先级

  优先级越高,越有可能先执行;Thread类中设置了两个方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
改变线程优先级:    public final void setPriority(int newPriority) ;
返回线程优先级:    public final void getPriority() ;

设置和取得优先级均使用int数据;且为final属性,不可改变。

  Thread类中也设置了三个常量字段值,分别约定了线程优先级的最高、中、最低三个级别

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
线程的最高优先级:    public static final int MAX_PRIORITY
线程的中等优先级:    public static final int NORM_PRIORITY
线程的最低优先级:    public static final int MIN_PRIORITY
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyThread implements Runnable {   
    @Override
    public void run() {

        for ( int x = 0 ; x < 20 ; x ++ ) {
            try { // 执行sleep休眠,休眠1秒(sleep是以纳秒为单位)
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ">>>" + x);
        }
    }
}
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread() ;
        Thread t1 = new Thread(mt,"线程 A");
        Thread t2 = new Thread(mt,"线程B");
        Thread t3 = new Thread(mt,"线程C");
        
        t1.start();
        t2.start();
        t3.start();
    }

}

上例代码中,运行执行的结果中,优先级没有设置,且顺序再每次输出都是不同的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread() ;
        Thread t1 = new Thread(mt,"线程 A");
        Thread t2 = new Thread(mt,"线程B");
        Thread t3 = new Thread(mt,"线程C");
        t1.setPriority(Thread.MAX_PRIORITY);  // 设置t1为最高优先级
        t1.start();
        t2.start();
        t3.start();
    }

}

本段主方法中的第9行,设置t1为最高优先级,于是t1越是有可能的优先执行(不是绝对)

主方法的优先级:

  主方法也是一个线程,但是主方法的优先级又是多少呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TestDemo {

    public static void main(String[] args) throws Exception {
        System.out.println(Thread.currentThread().getPriority());
    }

}

显示的结果为:【 5 】  所以主方法(主线程)的属于中等优先级

# 总结:

  1、Thread.currentThread:可以取得当前的线程类对象

  2、Thread.sleep():实现休眠功能

  3、优先级越高,越有可能先执行


线程的同步与死锁

线程的同步:

  所谓的同步指的是多个线程访问同一资源时的问题;即多个线程对象操作同一个对象资源。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyThread implements Runnable {   
    private int ticket = 5 ;   // 一共有5个点
    
    @Override
    public void run() {

        for ( int x = 0 ; x < 20; x ++ ) {
            if (this.ticket > 0) {
                System.out.println(Thread.currentThread().getName() + ticket--);
            }
        }
    }
}
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread();
        new Thread(mt,"A >>>").start();
        new Thread(mt,"B >>>").start();
        new Thread(mt,"C >>>").start();
    }

}

【运行结果】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A >>>5
A >>>2
A >>>1
C >>>3
B >>>4

此时,上例没有出现任何问题!

但——在代码run()的for中加入延迟【Thread.sleep();】就会出现问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyThread implements Runnable {   
    private int ticket = 5 ;   // 一共有5个点
    
    @Override
    public void run() {

        for ( int x = 0 ; x < 20; x ++ ) {
            if (this.ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ticket--);
            }
        }
    }
}
public class TestDemo {

    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread();
        new Thread(mt,"A >>>").start();
        new Thread(mt,"B >>>").start();
        new Thread(mt,"C >>>").start();
    }
}

【运行结果】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
B >>>3
A >>>4
C >>>5
B >>>2
A >>>1
C >>>0
B >>>-1

可以明显的发现,结果中出现了“负数”(意外值);这就是“不同步”的状况【异步操作】。

上例代码的想法是:从同一个资源取得当前的剩余的点数,但是由于延迟的存在,后续的线程不会等待之前的线程,会直接的进入,导致剩余值没有得到及时的刷新。

同步的操作

  所谓同步就是指多个线程操作同一时间只能有一个线程进入同一个空间运行,其他线程要等待此线程完成之后才可以继续执行。而之前的不同步【或称为异步操作】,则是多个线程可以同一时间进入同一个空间运行。

  Java中实现线程得同步则使用:synchronized 关键字。使用方法:1、同步代码块;2、[线程]同步方法;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Java 四种代码块:
    普通代码块、构造块、静态块、同步块

上例代码实现得则是“同步块”,利用synchronized关键字使得12~31行代码被关键字锁住,每一次执行只可以进入一个对象,实现同步。

所有(多个)线程,只有当里面得线程结束了,自己才可以进入同步块【一次只可以进入一个对象】

但是有人翻译同步代码块比较“粗糙”,所以还有另外得【同步方法】:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package hello;
 2 
 3 import java.util.concurrent.Callable;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.FutureTask;
 6 
 7 class MyThread implements Runnable {   
 8     private int ticket = 5 ;   // 一共有5个点
 9     
10     @Override
11     public void run() {
12 
13         for ( int x = 0 ; x < 20; x ++ ) {
14             this.sale(); // 调用同步方法
15         }
16     }
17     public synchronized void sale() {  // 同步方法
18         if (this.ticket > 0 ) {
19             try {
20                 Thread.sleep(1000);
21             } catch (InterruptedException e) {
22                 e.printStackTrace();
23             }
24             System.out.println(Thread.currentThread().getName() + ticket--);
25         }
26     }
27 }
28 public class TestDemo {
29 
30     public static void main(String[] args) throws Exception {
31         MyThread mt = new MyThread();
32         new Thread(mt,"A >>>").start();
33         new Thread(mt,"B >>>").start();
34         new Thread(mt,"C >>>").start();
35     }
36 }

上例代码则是放弃了同步块,使用同步方法实现“同步”。17~26行定义了同步方法:同步方法得定义结构依旧是使用synchronized关键字;(14行)在run()方法中,使用this方法调用同步方法。

【ps:异步操作得速度高于同步操作,而同步操作时得数据安全性高于异步操作时得数据安全性;】

死锁:

  所谓的同步就是一个线程对象等待另外一个线程对象执行完毕后的操作形式;线程同步过多,就有可能造成死锁。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package hello;
 2 
 3 import java.util.concurrent.Callable;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.FutureTask;
 6 
 7 class A {
 8     public synchronized void say(B b) {
 9         System.out.println("把你的本给我,我给你笔,否则不给!");
10         b.get();
11     }
12     public synchronized void get() {
13         System.out.println("得了本,付出了笔,还是什么都干不了!");
14     }
15 }
16 class B {
17     public synchronized void say(A a) {
18         System.out.println("把你的笔给我,我就给你本,否则不给!");
19         a.get();
20     }
21     public synchronized void get() {
22         System.out.println("得到了笔,付出了本,还是什么都干不了!");
23     }
24     
25 }
26 public class TestDemo implements Runnable{
27     private static A a = new A() ;
28     private static B b = new B() ;
29     public static void main(String[] args) throws Exception {
30         new TestDemo() ;
31     }
32     public TestDemo() {
33         new Thread(this).start();
34         b.say(a);
35     }
36     @Override
37     public void run() {
38         a.say(b);
39     }
40 }

上例是“死锁操作”,过多的同步线程,导致的死锁。【无意义代码】

死锁是程序开发中,由于某种逻辑上的错误所造成的问题;

# 同步产生的问题:

  1、多个线程访问同一空间资源是一定要处理好同步,可以使用同步代码块或同步方法解决;

  2、但是过多的同步,有可能造成“死锁”


# 总结:

  1、最简单的同步或异步操作,就是通过 synchronized 关键字实现。

  2、死锁是一种不定、不可预的状态。

---------

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-06-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Python的Albumentations库
对 ImageNet validation set 中的前 2000 张图片进行处理,采用 Intel Core i7-7800X CPU. 不同数据增强库的处理速度对比(以秒为单位,时间越少越好).
狼啸风云
2021/05/13
2.4K0
Python的Albumentations库
UNet 和 UNet++:医学影像经典分割网络对比
点击上方↑↑↑“OpenCV学堂”关注我来源:公众号 AI公园 授权 导读 在不同的任务上对比了UNet和UNet++以及使用不同的预训练编码器的效果。 介绍 语义分割是计算机视觉的一个问题,我们的任务是使用图像作为输入,为图像中的每个像素分配一个类。在语义分割的情况下,我们不关心是否有同一个类的多个实例(对象),我们只是用它们的类别来标记它们。有多种关于不同计算机视觉问题的介绍课程,但用一张图片可以总结不同的计算机视觉问题: 语义分割在生物医学图像分析中有着广泛的应用:x射线、MRI扫描、数字病理、
OpenCV学堂
2022/04/25
1.8K0
UNet 和 UNet++:医学影像经典分割网络对比
深度学习常用图像数据增强库albumentations系列教程(二)
在第一篇教程中,我们讲述了简单的图像增强技巧,本节通过使用Compose方法将各种图像增强的方法组合起来,形成一个图像增强的pipeline,方便产生大量不同种类的增强图片。
用户9875047
2022/12/07
1K0
深度学习常用图像数据增强库albumentations系列教程(二)
2D和3D数据增强方法和Python代码
在前面的文章里我们讲过,机器学习和深度学习在训练过程中,训练误差不断下降,但测试误差下降到一定程度后就会停止或者上升,出现过拟合现象,解决过拟合问题主要有2个方法,其中一个是正则化(机器学习和深度学习中的正则化方法),另一个方法就是数据增强了。
Minerva
2020/05/26
4.5K0
使用卷积神经网络预防疲劳驾驶事故
美国国家公路交通安全管理局估计,每年有 91,000 起车祸涉及疲劳驾驶的司机,造成约50,000 人受伤和近 800 人死亡。此外,每 24 名成年司机中就有 1 人报告在过去 30 天内在驾驶时睡着了。研究甚至发现,超过20个小时不睡觉相当于血液酒精浓度为0.08%——美国的法律规定的上限。
小白学视觉
2021/10/14
4800
pytorch DataLoader(3)_albumentations数据增强(分割版)
本文代码 系列前置文章: pytorch DataLoader(1): opencv,skimage,PIL,Tensor转换以及transforms pytorch DataLoader(2): Dataset,DataLoader自定义训练数据_opencv,skimage,PIL接口 翻译文章: 将Albumentations用于语义分割任务
烤粽子
2021/07/07
1.9K0
pytorch DataLoader(3)_albumentations数据增强(分割版)
一种目标检测任务中图像-标注对增强方法
其实,本篇应是深度学习常用图像数据增强库albumentations系列教程(三)的,但是鉴于不如现在的题目直观,还是修改了,原来两篇见如下:
用户9875047
2022/12/07
4620
Pytorch图像处理中数据扩增方案
本章对语义分割任务中常见的数据扩增方法进行介绍,并使用OpenCV和albumentations两个库完成具体的数据扩增操作。
听城
2021/03/02
1.3K0
Pytorch图像处理中数据扩增方案
用于数据增强的十个Python库
数据增强是人工智能和机器学习领域的一项关键技术。它涉及到创建现有数据集的变体,提高模型性能和泛化。Python是一种流行的AI和ML语言,它提供了几个强大的数据增强库。在本文中,我们将介绍数据增强的十个Python库,并为每个库提供代码片段和解释。
deephub
2023/10/06
5900
用于数据增强的十个Python库
基于CNN和LSTM的气象图降水预测示例
我们是否可以通过气象图来预测降水量呢?今天我们来使用CNN和LSTM进行一个有趣的实验。
自学气象人
2023/01/12
1.5K1
【验证码识别专栏】今天不炼丹,用 cv 来秒验证码
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
K哥爬虫
2024/12/02
2610
【验证码识别专栏】今天不炼丹,用 cv 来秒验证码
【Keras】基于SegNet和U-Net的遥感图像语义分割
上两个月参加了个比赛,做的是对遥感高清图像做语义分割,美其名曰“天空之眼”。这两周数据挖掘课期末project我们组选的课题也是遥感图像的语义分割,所以刚好又把前段时间做的成果重新整理和加强了一下,故写了这篇文章,记录一下用深度学习做遥感图像语义分割的完整流程以及一些好的思路和技巧。 数据集 首先介绍一下数据,我们这次采用的数据集是CCF大数据比赛提供的数据(2015年中国南方某城市的高清遥感图像),这是一个小数据集,里面包含了5张带标注的大尺寸RGB遥感图像(尺寸范围从3000×3000到6000×600
机器学习AI算法工程
2018/04/17
3.9K0
【Keras】基于SegNet和U-Net的遥感图像语义分割
特征类型和图像分割
我们最想检测的就是角点,因为角点是可重复性最高的特征,也就是说因为角点是可重复性最高的特征,给出关于同一景象的两张或以上图像 我们就能很轻易地识别出这类特征。 举一个简单的例子:
小飞侠xp
2018/08/29
1.1K0
Mask R-CNN上手指南:对象检测和分割实现无人机的检测
目标检测是一种计算机视觉技术,用于识别和定位图像中的目标。有很多检测算法存在,这里是对Mask R-CNN的一个很好的总结。
deephub
2020/05/09
8770
Mask R-CNN上手指南:对象检测和分割实现无人机的检测
最快最好用的图像处理库:albumentations库的简单了解和使用
在对图片进行处理的时候,之前就使用torch自带的transfrom来对图像做一些反转,平移,随机剪裁,拉伸这样的任务。然而最近的图像分类+语义分割的比赛中,发现了这样的一个库函数:Albumentations。
机器学习炼丹术
2020/07/14
11.6K0
最快最好用的图像处理库:albumentations库的简单了解和使用
Python的人脸自动戴口罩系统
2019年新型冠状病毒感染的肺炎疫情发生以来,牵动人心,举国哀痛,口罩、酒精、消毒液奇货可居。
IT茂茂
2020/03/05
7380
Python的人脸自动戴口罩系统
动手实践系列:CV语义分割!
图像分割是计算机视觉中除了分类和检测外的另一项基本任务,它意味着要将图片根据内容分割成不同的块。相比图像分类和检测,分割是一项更精细的工作,因为需要对每个像素点分类。
Datawhale
2021/12/08
9730
动手实践系列:CV语义分割!
Imgaug之导入和增强图像
在机器视觉领域,想将深度学习应用于实际工程项目,并最终落地,会遇到很多问题:光照、遮挡等。而采集到的数据通常难以满足各种现实环境,需要进行数据增强操作。 imgaug是一个基于OpenCV的更高级的API,包含很多集成好的图像增强的方法。
狼啸风云
2021/03/16
2K0
Imgaug之导入和增强图像
【GPTs】Gif-PT:DALL·E制作创意动图与精灵动画
【AIGC】如何在ChatGPT中制作个性化GPTs应用详解 https://blog.csdn.net/2201_75539691?type=blog
CSDN-Z
2024/11/15
1650
【GPTs】Gif-PT:DALL·E制作创意动图与精灵动画
语义分割 - 数据集准备
# 语义分割数据集准备 Dataset 数据集下载 PASCAL VOC 2012 dataset augmented PASCAL VOC dataset # augmented PASCAL VOC cd $DATASETS wget http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/semantic_contours/benchmark.tgz # 1.3 GB tar -zxvf benchmark.tgz
AIHGF
2019/02/18
1.4K0
推荐阅读
相关推荐
Python的Albumentations库
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档