Tôi tự hỏi liệu có cách "thông minh" tách hình ảnh dựa trên các tính năng nhất định không.Cách tách hình ảnh thành hai với java
Hình ảnh có kích thước 300x57, đen trắng (màu xám hoặc trắng), bao gồm hai tính năng chính (hãy gọi chúng là các đốm màu) được phân tách bằng khoảng trắng, mỗi đốm hơi hơi khác nhau về chiều rộng và chiều cao, vị trí của các đốm màu cũng thay đổi, các đốm màu KHÔNG BAO GIỜ trùng lặp!
Đây là những gì một hình ảnh "có vẻ" như:
-------------------------
----WWW---------WWWWW----
---WWWWWWW----WWWWWW-----
-----WWWW-------WWW------
-------------------------
Việc phân chia kết quả sẽ là một cái gì đó như thế này:
------------ -------------
----WWW----- ----WWWWW----
---WWWWWWW-- --WWWWWW-----
-----WWWW--- ----WWW------
------------ -------------
bước tôi có kế hoạch đi qua để chia hình ảnh:
- Quét hình ảnh từ bên này sang bên kia.
- Xác định các cạnh của các đốm màu.
- Lấy khoảng cách giữa hai cạnh bên trong.
- Tách hình ảnh ở giữa khoảng cách bên trong.
- Lưu hai hình ảnh dưới dạng các tệp riêng biệt.
Sẽ tốt hơn nếu tôi chuẩn hóa độ rộng hình ảnh, vì vậy tất cả hình ảnh của tôi đều có chiều rộng đồng đều khi chúng được lưu.
Tôi không có kinh nghiệm về thao tác hình ảnh, vì vậy tôi không biết cách hiệu quả để thực hiện việc này là gì. Tôi hiện đang sử dụng BufferedImage, nhận chiều rộng/chiều cao, lặp lại trên mỗi pixel, v.v. Không có giải pháp nào cho vấn đề của tôi, nhưng tôi đang tìm một giải pháp hiệu quả hơn (ít mã hơn + nhanh hơn). Tôi cũng đã xem xét java.awt.Graphics ...
Tôi sẽ đánh giá cao nếu tôi nhận được một số ý tưởng cho các cách hiệu quả hơn để thực hiện tác vụ này. Tôi muốn gắn bó với các thư viện tích hợp của Java, vì vậy BufferedImage hoặc Graphics2D là thứ hiệu quả nhất để sử dụng trong trường hợp này?
EDIT: Đây là đoạn mã sau khi đọc những gợi ý:
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"));
}
Lưu ý: sau khi phát hiện cạnh phải, bạn có thể dễ dàng thoát ra khỏi vòng lặp for. – Kiril