Мне интересно, есть ли «умный» способ разделения изображения на основе определенных функций.Как отделить изображение от двух с java
Изображения 300x57, черно-белые (на самом деле оттенки серого, но большинство цветов либо черные, либо белые), он состоит из двух основных функций (назовем их капли), разделенных черным пространством, каждый кадр немного изменяется по ширине и высота, положение капель тоже меняется, капли НИКОГДА не перекрываются!
Вот что образ «выглядит» как:
-------------------------
----WWW---------WWWWW----
---WWWWWWW----WWWWWW-----
-----WWWW-------WWW------
-------------------------
В результате раскола было бы что-то вроде этого:
------------ -------------
----WWW----- ----WWWWW----
---WWWWWWW-- --WWWWWW-----
-----WWWW--- ----WWW------
------------ -------------
шаги я планирую предпринять, чтобы разбить изображение:
- Сканирование изображения с одной стороны на другую.
- Определите края капель.
- Возьмите расстояние между двумя внутренними краями.
- Разделить изображение в середине внутреннего расстояния.
- Сохраните два изображения в виде отдельных файлов.
Было бы неплохо, если бы я нормализовал ширину изображения, поэтому все мои изображения имеют единую ширину при их сохранении.
У меня нет опыта манипуляции с изображениями, поэтому я не знаю, что это эффективный способ сделать это. В настоящее время я использую BufferedImage, получая ширину/высоту, итерацию по каждому пикселю и т. Д. Для моей проблемы нет неправильного решения, но я ищу более эффективный (меньше кода + быстрее). Я также изучал java.awt.Graphics ...
Буду признателен, если я получу несколько идей для более эффективных способов выполнения этой задачи. Я хочу использовать встроенные библиотеки 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"));
}
Примечание: после обнаружения правого края можно просто вырваться из цикла for. – Kiril