今天我尝试在Python中编写一个我用Java编写的程序,用于将背景与文本图像隔离开来。 而且我无法弄清楚为什么我的Python程序执行速度比我的Java程序慢得多(在Java中花费不到一秒钟,在Python中花费不到5分钟),尽管它们几乎完全相同。
我想提一下我对Python很陌生,所以如果我犯了一个明显的错误,我很抱歉。
这是Python代码:
import random
import math
from PIL import Image
from pythonds.basic.stack import Stack
def isolatebackground(image, max_distance):
newimage = image.copy()
(width, height) = image.size
w = random.randrange(width);
h = random.randrange(height);
# Preparing unvisited pixels
unvisitedpixels = []
for x in range(width):
for y in range(height):
unvisitedpixels.append((x,y))
# Background pixels
background = []
stack = Stack()
stack.push((x,y))
(width, height) = image.size
pixels = image.load()
unvisitedpixels.remove((x,y))
possibleneighbors = [i for i in range(8)]
translations = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)]
# Region growing algorithm
while not stack.isEmpty():
(currentred, currentgreen, currentblue, currentalpha) = pixels[x, y]
foundneighbor = False
unvisitedneighbors = possibleneighbors.copy()
while len(unvisitedneighbors) > 0:
n = random.choice(unvisitedneighbors)
unvisitedneighbors.remove(n)
(i, j) = translations[n]
newX = x + i
newY = y + j
if newX >= 0 and newX < width and newY >= 0 and newY < height:
if (newX, newY) in unvisitedpixels:
unvisitedpixels.remove((newX, newY))
(newred, newgreen, newblue, newalpha) = pixels[newX, newY]
distance = math.sqrt((newred - currentred) ** 2 + (newgreen - currentgreen) ** 2 + (newblue - currentblue) ** 2)
if distance <= max_distance:
foundneighbor = True
background.append((newX, newY))
stack.push((newX, newY))
(x, y) = (newX, newY)
if not foundneighbor:
(x,y) = stack.pop()
for p in background:
newimage.putpixel(p, (255, 0, 0))
return newimage
if __name__ == '__main__':
image = Image.open("TestImage3.png")
newimage = isolatebackground(image, 5)
newimage.show()
Java代码:
Main.java:
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import javax.imageio.ImageIO;
public class Main
{
public static void main(String[] args) throws IOException
{
BufferedImage im = readImage("TestImage3.png");
BufferedImage split_im = removeBackground(im, 5);
File f1 = new File("test.png");
ImageIO.write(split_im, "png", f1);
}
public static BufferedImage readImage(String path) throws IOException
{
File image_file = new File(path);
BufferedImage image = ImageIO.read(image_file);
return image;
}
public static BufferedImage removeBackground (BufferedImage image, double threshold)
{
BufferedImage split_im = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = split_im.getGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
int x = (int)(image.getWidth() * Math.random());
int y = (int)(image.getHeight() * Math.random());
split_im.setRGB(x, y, Color.RED.getRGB());
int[][] translations = {{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}};
List<Integer> possibleNeighbors = new ArrayList<>();
for (int i = 0; i < 8; i++)
{
possibleNeighbors.add(i);
}
Map<Coordinates, Integer> unvisitedPixels = new HashMap<>();
for (int h = 0; h < image.getHeight(); h++)
{
for (int w = 0; w < image.getWidth(); w++)
{
unvisitedPixels.put(new Coordinates(w, h), image.getRGB(w, h));
}
}
Coordinates initialCoord = new Coordinates(x, y);
unvisitedPixels.remove(initialCoord);
Stack visitedPixels = new Stack();
visitedPixels.push(initialCoord);
while (!visitedPixels.empty())
{
Color c1 = new Color(image.getRGB(x, y));
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
boolean foundNeighbor = false;
List<Integer> unvisitedNeighbors = new ArrayList<>(possibleNeighbors);
while (!unvisitedNeighbors.isEmpty())
{
int n = (int)(8 * Math.random());
if (unvisitedNeighbors.contains(n))
{
unvisitedNeighbors.remove(unvisitedNeighbors.indexOf(n));
int[] translation = translations[n];
int newX = x + translation[0];
int newY = y + translation[1];
if (newX >= 0 && newX < image.getWidth() && newY >= 0 && newY < image.getHeight())
{
Coordinates coord = new Coordinates(newX, newY);
Integer value = unvisitedPixels.get(coord);
if (value != null)
{
Color c2 = new Color(value);
int r2 = c2.getRed();
int g2 = c2.getGreen();
int b2 = c2.getBlue();
double distance = Math.sqrt(Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2));
if (distance <= threshold)
{
foundNeighbor = true;
split_im.setRGB(x, y, Color.RED.getRGB());
unvisitedPixels.remove(coord);
x = newX;
y = newY;
visitedPixels.push(coord);
}
}
}
}
}
if (!foundNeighbor)
{
Coordinates newCoord = (Coordinates)visitedPixels.pop();
x = newCoord.getX();
y = newCoord.getY();
}
}
return split_im;
}
}
Coordinates.java:
public class Coordinates
{
private int x;
private int y;
public Coordinates(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public String toString() {
return "Coordinates{" + "x=" + x + ", y=" + y + '}';
}
@Override
public int hashCode() {
int hash = 7;
hash = 73 * hash + this.x;
hash = 73 * hash + this.y;
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
{
return false;
}
else if (!(obj instanceof Coordinates))
{
return false;
}
else
{
Coordinates other = (Coordinates)obj;
return this.x == other.getX() && this.y == other.getY();
}
}
}
我使用此图像作为测试:(分辨率较低,否则Python程序需要很长时间才能对其进行分析)。
你知道什么可能导致Python中这么糟糕的表现吗?
谢谢!