3 개 이미지의 총 픽셀을 동시에 계산하려면 어떻게해야합니까? Java Swing Worker 및 Thread로 시도했지만 답변을 얻었지만 지정된 범위의 총 픽셀 수 (각 이미지에 대해 30 초, 이미지 크기 480 * 303)를 반환하는 데 1.30 분이 걸립니다. 하지만 30 초 이내에 동시에 세 개의 이미지에 대한 답을 얻어야합니다.
public class ImageProcessor1 implements Runnable{
static int blackPix=0;
BufferedImage tempImg;
public static int blackPixel=0;
public ImageProcessor1(String path) throws Exception{
tempImg = ImageIO.read(new File(path));
}
private static int[] getPixelData(BufferedImage img, int x, int y) {
int argb = img.getRGB(x, y);
int rgb[] = new int[]{
(argb >> 16) & 0xff, //red
(argb >> 8) & 0xff, //green
(argb) & 0xff //blue
};
System.out.println("Process1 :rgb: " + rgb[0] + " " + rgb[1] + " " + rgb[2]);
return rgb;
}
@Override
public void run() {
int[][] pixelData = new int[tempImg.getHeight() * tempImg.getWidth()][3];
int[] rgb;
int height=tempImg.getHeight();
int width=tempImg.getWidth();
int counter = 0;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
rgb = getPixelData(tempImg, i, j);
if(rgb[0]<125 && rgb[0]>105 && rgb[1]<125 && rgb[1]>105 && rgb[2]<125 && rgb[2]>105)
{
blackPixel+=1;
}
}
}
}
}
이렇게 작은 사진을 반복하는 데 30 초가 걸린다는 것은 매우 이상합니다!
약간의 프로파일 링 후 핫 루프에서 println-statement를 사용하면 속도가 크게 느려지는 것 같습니다.
코드를 약간 수정 한 후 10500x5788 이미지는 내 컴퓨터에서 ~ 3 초가 걸립니다.
수정 된 버전 :
package application;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
public class ImageProcessor1 implements Runnable {
BufferedImage tempImg;
public static int blackPixel = 0;
public ImageProcessor1(final String path) throws Exception {
final long start = System.nanoTime();
tempImg = ImageIO.read(new File(path));
// Use tracing, profiling and sampling to proof performance issues and fixes
System.out.println("ImageIO took " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)
+ " ms.");
}
@Override
public void run() {
long start = System.nanoTime();
final int height = tempImg.getHeight();
System.out.println("Getting height '" + height + "' took "
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " ms.");
start = System.nanoTime();
final int width = tempImg.getWidth();
System.out.println("Getting width '" + width + "' took "
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " ms.");
start = System.nanoTime();
// reuse variables
int argb;
int red;
int green;
int blue;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
// HOT LOOP. Do as little as possible. No println calls!
argb = tempImg.getRGB(i, j);
// inline all method calls
red = argb >> 16 & 0xff; // red
green = argb >> 8 & 0xff; // green
blue = argb & 0xff; // blue
if (red < 125 && red > 105 && green < 125 && green > 105 && blue < 125 && blue > 105) {
blackPixel += 1;
}
}
}
System.out.println("Iterating pixels took "
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " ms.");
}
public static void main(final String[] args) throws Exception {
new ImageProcessor1("big.jpg").run();
System.out.println("Number of blackpixels = " + blackPixel);
}
}
보다 일반적인 메모에서 모든 이미지를 RAM으로 읽어 들인 다음 처리하기 때문에 접근 방식에주의해야합니다. 한 번에 3 개 이상의 큰 이미지를 사용하면 OutOfMemoryError가 발생할 가능성이 있습니다. 이것이 문제가되는 경우 이미지를 입력 스트림으로 읽고 한 번에 이미지의 작은 버퍼 만 처리 할 수 있습니다.
이를 수행하는 방법을 보려면 http://imagej.nih.gov/ij/source/ij/io/ImageReader.java를 참조하십시오 .
다중 스레드의 출력을 누적하는 방법을 보려면 다중 스레드 코드를 작성하고 모든 스레드의 출력을 단일 파일에 누적하는 방법을 참조하십시오 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다