Có hai cách bạn có thể tiếp cận điều này, tùy thuộc vào tùy chọn của bạn.
Phương pháp # 1 - Sử dụng bwareaopen
Một cách rẻ tiền để làm điều này sẽ được đảo ngược hình ảnh để các điểm ảnh đối tượng có màu trắng thay vì màu đen, sau đó thực hiện một đóng hình thái vào hình ảnh và loại bỏ những lĩnh vực mà rơi vào một số tiền nhất định. Việc đóng sẽ tham gia các vùng bị ngắt kết nối với nhau và lợi dụng việc tham gia "cấu trúc" sẽ tạo ra một khu vực có diện tích lớn, bạn có thể ngưỡng theo khu vực của mỗi khu vực và loại bỏ các khu vực đó dưới một mức nhất định.
Sau đó, bạn có thể lấy lại hình ảnh gốc bằng cách thực hiện một cách hợp lý AND
với hình ảnh ngược và kết quả đã đóng, sau đó hoàn nguyên kết quả trung gian này. Hiệu quả của điều này sẽ là chúng tôi chỉ giữ các pixel thuộc về hình ảnh ban đầu do hoạt động đóng các pixel đối tượng tạo nhân tạo. Cụ thể, việc kết hợp các vùng lân cận của cấu trúc sẽ tạo các pixel đối tượng mới và do đó, việc thực hiện một AND
sẽ đảm bảo rằng các pixel đó không giống với pixel gốc bị xóa. Vì điều này được thực hiện ở mặt sau của kết quả ban đầu, việc quay trở lại sẽ đưa bạn trở lại miền gốc của các pixel đối tượng là màu đen thay vì màu trắng.
Something như thế này:
%// Read in image from StackOverflow
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
%// Remove regions whose areas fall below 10000 pixels
out = bwareaopen(out, 10000);
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
Chúng tôi nhận được hình ảnh này:
Ghi chú
- Chức năng
imclose
sẽ thực hiện việc đóng cửa hình thái cho bạn với một yếu tố cấu được xác định bởi strel
. Tôi đã sử dụng một hình vuông 50 x 50 để đảm bảo rằng chúng ta có một cửa sổ đủ lớn để nối các pixel đối tượng lân cận lại với nhau.
- Chức năng
bwareaopen
chụp ảnh nhị phân và loại bỏ các khu vực có diện tích pixel nằm dưới một mức nhất định. Sau khi kết thúc, bạn sẽ có hai vùng được kết nối - phần đầu của hình ảnh với cấu trúc và phần cuối cùng với văn bản. Bằng cách thử nghiệm, 10.000 pixel đã xóa khu vực ở dưới cùng.
Phương pháp # 2 - Sử dụng regionprops
Liên quan đến Phương pháp # 1, một phương pháp khác để làm điều này và trở thành ngưỡng thuyết bất khả tri là để đi với ý tưởng ban đầu của bạn. Thực hiện thao tác đóng, nhưng sau đó đánh giá các vùng của từng vùng được kết nối và chọn vùng có diện tích lớn nhất. Những gì tôi đề nghị là sử dụng regionprops
trong trường hợp đó, đó là một chức năng được thiết kế đặc biệt để phân tích đặc điểm của khu vực hình ảnh riêng biệt. Đầu ra sẽ là cấu trúc của các phần tử N
, trong đó N
là tổng số đối tượng duy nhất và được kết nối được tìm thấy trong hình ảnh và mỗi cấu trúc chứa các trường thuộc tính bạn muốn đo trong hình ảnh. Trong trường hợp của bạn, hãy chỉ định các thuộc tính 'Area'
và 'PixelIdxList'
chứa các vị trí pixel và khu vực chính của từng khu vực.
Bạn sẽ tìm thấy tổng diện tích tối đa và sử dụng vị trí pixel tương ứng và đặt bản đồ đầu ra mà bạn muốn hợp lý AND
bằng.
Something như thế này:
%// Read in image from StackOverflow
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
s = regionprops(out, 'Area', 'PixelIdxList'); %// Apply regionprops
%// Find the region with the max area
[~,id] = max([s.Area]);
%// Create an output mask with the largest area
%// Make logical
out = false(size(im));
%// Set pixels from largest area
out(s(id).PixelIdxList) = true;
%// Rest of the logic from before
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
Bạn sẽ nhận được chính xác kết quả tương tự như phương pháp đầu tiên.
Câu hỏi có thể âm thanh ngu ngốc, nhưng sự khác biệt giữa các phần bạn muốn và các phần bạn không muốn là gì? Cả hai đều là dòng và ký tự. Có thể phát hiện khoảng cách thẳng đứng (sử dụng tổng hàng) và chia nhỏ ở đó? Có thể sử dụng imerode để kết nối cả hai khu vực màu đen, sau đó phân đoạn với bwlabel? – Daniel