Мне интересно, существует ли "умный" способ разделения изображения на основе определенных функций.
Изображения размером 300x57, черно-белые (на самом деле это оттенки серого, но большинство цветов - черный или белый), они состоят из двух основных функций (назовем их каплями), разделенных черным пространством, каждая капля слегка изменяется по ширине и высота, положение капель также меняется, капли НИКОГДА не перекрываются!
Вот как «выглядит» изображение:
-------------------------
----WWW---------WWWWW----
---WWWWWWW----WWWWWW-----
-----WWWW-------WWW------
-------------------------
Получившийся сплит будет выглядеть примерно так:
------------ -------------
----WWW----- ----WWWWW----
---WWWWWWW-- --WWWWWW-----
-----WWWW--- ----WWW------
------------ -------------
Шаги, которые я планирую предпринять, чтобы разделить изображение:
- Сканирование изображения с одной стороны на другую.
- Определить края капель.
- Возьмите расстояние между двумя внутренними краями.
- Разделить изображение на середину внутреннего расстояния.
- Сохраните два изображения в виде отдельных файлов.
Было бы неплохо, если бы я нормализовал ширину изображения, чтобы при сохранении все мои изображения имели одинаковую ширину.
У меня нет опыта работы с изображениями, поэтому я не знаю, как это эффективно сделать. В настоящее время я использую BufferedImage, получаю ширину / высоту, перебираю каждый пиксель и т. Д. Для моей проблемы нет неправильного решения, но я ищу более эффективное (меньше кода + быстрее). Я также изучал java.awt. Графика ...
Буду признателен, если у меня появятся идеи для более эффективных способов решения этой задачи. Я хочу придерживаться встроенных библиотек Java, поэтому BufferedImage или Graphics2D наиболее эффективная вещь для использования в этом случае?
EDIT:
Вот код после прочтения предложений:
public void splitAndSaveImage( BufferedImage image ) throws IOException
{
// Process image ------------------------------------------
int height = image.getHeight();
int width = image.getWidth();
boolean edgeDetected = false;
double averageColor = 0;
int threshold = -10;
int rightEdge = 0;
int leftEdge = 0;
int middle = 0;
// Scan the image and determine the edges of the blobs.
for(int w = 0; w < width; ++w)
{
for(int h = 0; h < height; ++h)
{
averageColor += image.getRGB(w, h);
}
averageColor = Math.round(averageColor/(double)height);
if( averageColor /*!=-1*/< threshold && !edgeDetected )
{
// Detected the beginning of the right blob
edgeDetected = true;
rightEdge = w;
}else if( averageColor >= threshold && edgeDetected )
{
// Detected the end of the left blob
edgeDetected = false;
leftEdge = leftEdge==0? w:leftEdge;
}
averageColor = 0;
}
// Split the image at the middle of the inside distance.
middle = (leftEdge + rightEdge)/2;
// Crop the image
BufferedImage leftImage = image.getSubimage(0, 0, middle, height);
BufferedImage rightImage = image.getSubimage(middle, 0, (width-middle), height);
// Save the image
// Save to file -------------------------------------------
ImageIO.write(leftImage, "jpeg", new File("leftImage.jpeg"));
ImageIO.write(rightImage, "jpeg", new File("rightImage.jpeg"));
}