基于多线程java的图像阈值分割
我有一个学校项目,我们应该使用并行编程来加快算法的运行速度。例如,我选择了图像阈值 所以我创建了Java程序,正常运行(加载图像,循环所有像素,计算阈值,再次循环所有像素,设置黑色或白色,如果大于或小于阈值)。 这在我的笔记本上花费了约5秒的时间,照片约为4000x3000,图像约为11500x11500,花费了约49秒 然后我创建了另一个程序,它应该使用线程,以使它们更快地完成循环 现在我创建了4个线程,每个线程处理图像的1/4。首先,他们向synchronized arraylist中添加threshold vlaues,在完成所有操作后,我计算阈值。然后我再创建4个线程,它们再次处理图像的1/4,并在图片中设置黑色或白色 4000x3000映像占用了我12秒,11500x11500映像占用了java.lang.OutOfMemoryError:java堆空间(在所有线程中)基于多线程java的图像阈值分割,java,multithreading,image-processing,Java,Multithreading,Image Processing,我有一个学校项目,我们应该使用并行编程来加快算法的运行速度。例如,我选择了图像阈值 所以我创建了Java程序,正常运行(加载图像,循环所有像素,计算阈值,再次循环所有像素,设置黑色或白色,如果大于或小于阈值)。 这在我的笔记本上花费了约5秒的时间,照片约为4000x3000,图像约为11500x11500,花费了约49秒 然后我创建了另一个程序,它应该使用线程,以使它们更快地完成循环 现在我创建了4个线程,每个线程处理图像的1/4。首先,他们向synchronized arraylist中添加t
public class PprPrahovaniParalelne{
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
final Threshold image = new Threshold(nactiObrazek("ryba.jpg"));
final int width = image.getImage().getWidth();
final int height = image.getImage().getHeight();
Thread t1 = new Thread(){
int threshold;
public void run(){
System.out.println("Thread 1 - Started");
for(int y = 0; y < height/4;y++){
for(int x = 0; x < width;x++){
Color color = new Color(image.getImage().getRGB(x,y));
threshold = (color.getRed()+color.getGreen()+color.getBlue())/3;
image.addThreshold(threshold);
}
}
System.out.println("Thread 1 - finished");
}
};
Thread t2 = new Thread(){
int threshold;
@Override
public void run(){
for(int y = height/4; y < height/4*2;y++){
for(int x = 0; x < width;x++){
Color barva = new Color(image.getImage().getRGB(x,y));
threshold = (barva.getRed()+barva.getGreen()+barva.getBlue())/3;
image.addThreshold(threshold);
}
}
System.out.println("Thread 2 - finished");
}
};
Thread t3 = new Thread(){
int threshold;
@Override
public void run(){
for(int y = height/4*2; y < height/4*3;y++){
for(int x = 0; x < width;x++){
Color barva = new Color(image.getImage().getRGB(x,y));
threshold = (barva.getRed()+barva.getGreen()+barva.getBlue())/3;
image.addThreshold(threshold);
}
}
System.out.println("Thread 3 - finished");
}
};
Thread t4 = new Thread(){
int threshold;
@Override
public void run(){
for(int y = height/4*3; y < height;y++){
for(int x = 0; x < width;x++){
Color barva = new Color(image.getImage().getRGB(x,y));
threshold = (barva.getRed()+barva.getGreen()+barva.getBlue())/3;
image.addThreshold(threshold);
}
}
System.out.println("Thread 4 - finished");
}
};
t1.start();
t2.start();
t4.start();
t3.start();
try{
t1.join();
t2.join();
t3.join();
t4.join();
}catch(InterruptedException e){
e.printStackTrace();
}
image.countThreshold();
System.out.println("Threshold je: " + image.getThreshold());
Thread t5 = new Thread(){
Color cerna = new Color(255,255,255);
Color bila = new Color(0,0,0);
int threshold;
@Override
public void run(){
for(int y = 0; y < height/4;y++){
for(int x = 0; x < width;x++){
Color barva = new Color(image.getImage().getRGB(x,y));
threshold = (barva.getRed()+barva.getGreen()+barva.getBlue())/3;
if(threshold > image.getThreshold()){
image.getImage().setRGB(x, y, cerna.getRGB());
}else{
image.getImage().setRGB(x, y, bila.getRGB());
}
}
}
System.out.println("Thread 5 - finished");
}
};
Thread t6 = new Thread(){
Color cerna = new Color(255,255,255);
Color bila = new Color(0,0,0);
int threshold;
@Override
public void run(){
for(int y = height/4; y < height/4*2;y++){
for(int x = 0; x < width;x++){
Color color = new Color(image.getImage().getRGB(x,y));
threshold = (color.getRed()+color.getGreen()+color.getBlue())/3;
if(threshold > image.getThreshold()){
image.getImage().setRGB(x, y, cerna.getRGB());
}else{
image.getImage().setRGB(x, y, bila.getRGB());
}
}
}
System.out.println("Thread 6 - finished");
}
};
Thread t7 = new Thread(){
Color cerna = new Color(255,255,255);
Color bila = new Color(0,0,0);
int threshold;
@Override
public void run(){
for(int y = height/4*2; y < height/4*3;y++){
for(int x = 0; x < width;x++){
Color color = new Color(image.getImage().getRGB(x,y));
threshold = (color.getRed()+color.getGreen()+color.getBlue())/3;
if(threshold > image.getThreshold()){
image.getImage().setRGB(x, y, cerna.getRGB());
}else{
image.getImage().setRGB(x, y, bila.getRGB());
}
}
}
System.out.println("Thread 7 - finished");
}
};
Thread t8 = new Thread(){
Color cerna = new Color(255,255,255);
Color bila = new Color(0,0,0);
int threshold;
@Override
public void run(){
for(int y = height/4*3; y < height;y++){
for(int x = 0; x < width;x++){
Color barva = new Color(image.getImage().getRGB(x,y));
threshold = (barva.getRed()+barva.getGreen()+barva.getBlue())/3;
if(threshold > image.getThreshold()){
image.getImage().setRGB(x, y, cerna.getRGB());
}else{
image.getImage().setRGB(x, y, bila.getRGB());
}
}
}
System.out.println("Thread 8 - finished");
}
};
t5.start();
t6.start();
t7.start();
t8.start();
try{
t5.join();
t6.join();
t7.join();
t8.join();
}catch(InterruptedException e){
e.printStackTrace();
}
File hotovo = new File("ryba_prahovanej.jpg");
ImageIO.write(image.getImage(), "jpg", hotovo);
}
public static BufferedImage nactiObrazek(String nazev){
BufferedImage img = null;
try {
img = ImageIO.read(new File(nazev));
} catch (IOException e) {
}
return img;
}
}
公共类PPRPRAHOVANIPARALLENE{
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args)引发IOException{
最终阈值图像=新阈值(nactiObrazek(“ryba.jpg”);
final int width=image.getImage().getWidth();
最终整数高度=image.getImage().getHeight();
线程t1=新线程(){
int阈值;
公开募捐{
System.out.println(“线程1-已启动”);
对于(int y=0;yimage.getThreshold()){
image.getImage().setRGB(x,y,cerna.getRGB());
}否则{
getImage().setRGB(x,y,bila.getRGB());
}
}
}
System.out.println(“螺纹5-完成”);
}
};
线程t6=新线程(){
颜色cerna=新颜色(255255);
颜色bila=新颜色(0,0,0);
int阈值;
@凌驾
公开募捐{
对于(int y=height/4;yimage.getThreshold()){
image.getImage().setRGB(x,y,cerna.getRGB());
}否则{
getImage().setRGB(x,y,bila.getRGB());
}
}
}
System.out.println(“螺纹6-完成”);
}
};
线程t7=新线程(){
public class Threshold {
private BufferedImage image;
final private List<Integer> list;
private int threshold;
public int getThreshold() {
return threshold;
}
public List<Integer> getList(){
return list;
}
public Threshold(BufferedImage obrazek) {
this.list = Collections.synchronizedList(new ArrayList<Integer>());
this.image = obrazek;
}
public void setObrazek(BufferedImage obrazek){
this.image = obrazek;
}
public BufferedImage getImage(){
return this.image;
}
public void addThreshold(int threshold){
list.add(threshold);
}
public void countThreshold(){
long sum = 0;
for (Iterator<Integer> it = list.iterator(); it.hasNext();) {
int item = it.next();
sum += item;
}
this.threshold = (int) (sum/list.size());
}
}
import java.awt.image.*;
import java.io.*;
import java.awt.*;
import javax.imageio.*;
import java.util.concurrent.*;
public class PprPrahovaniParalelne {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
final Threshold image = new Threshold(nactiObrazek("DSC03691.jpg"));
final int width = image.getImage().getWidth();
final int height = image.getImage().getHeight();
final int nCpu = Runtime.getRuntime().availableProcessors() + 1;
ExecutorService threadPool = Executors.newFixedThreadPool(nCpu);
System.out.println("Number of CPUs : "+nCpu);
CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new Runnable() {
private int count = 1;
public void run() {
if(count == 1) {
image.countThreshold();
System.out.println("Threshold je: " + image.getThreshold());
} else {
try {
File hotovo = new File("ryba_prahovanej.jpg");
ImageIO.write(image.getImage(), "jpg", hotovo);
} catch(IOException e) {
System.err.println("Error while writing : " + e);
}
threadPool.shutdownNow();
}
count++;
}
});
threadPool.submit(new ImageProcessingTask(0, height/4, width, image, cyclicBarrier));
threadPool.submit(new ImageProcessingTask(height/4, height/4*2, width, image, cyclicBarrier));
threadPool.submit(new ImageProcessingTask(height/4*2, height/4*3, width, image, cyclicBarrier));
threadPool.submit(new ImageProcessingTask(height/4*3, height, width, image, cyclicBarrier));
}
public static BufferedImage nactiObrazek(String nazev){
BufferedImage img = null;
try {
img = ImageIO.read(new File(nazev));
} catch (IOException e) {
}
return img;
}
}
class ImageProcessingTask implements Runnable {
private int start;
private int height;
private int width;
private Threshold image;
private CyclicBarrier barrier;
public ImageProcessingTask(int start, int height, int width, Threshold image, CyclicBarrier barrier) {
this.start = start;
this.height = height;
this.width = width;
this.image = image;
this.barrier = barrier;
}
public void run(){
int threshold;
System.out.println(Thread.currentThread().getName()+" - Started");
for(int y = start; y < height;y++){
for(int x = 0; x < width;x++){
Color color = new Color(image.getImage().getRGB(x,y));
threshold = (color.getRed()+color.getGreen()+color.getBlue())/3;
image.addThreshold(threshold);
}
}
try {
int count = barrier.await();
if(count == 0) {
barrier.reset();
System.out.println("Resetting Cyclic Barrier");
}
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
} catch(Exception e) {
e.printStackTrace();
}
Color cerna = new Color(255,255,255);
Color bila = new Color(0,0,0);
for(int y = start; y < height;y++){
for(int x = 0; x < width;x++){
Color barva = new Color(image.getImage().getRGB(x,y));
threshold = (barva.getRed()+barva.getGreen()+barva.getBlue())/3;
if(threshold > image.getThreshold()){
image.getImage().setRGB(x, y, cerna.getRGB());
}else{
image.getImage().setRGB(x, y, bila.getRGB());
}
}
}
try {
barrier.await();
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
} catch(Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" - finished");
}
}