1

Так что это в основном что-то очень простое, так как просто получить горизонтальный проекционный сюжет и получить местоположение линий на изображении. Но проблема в том, что применяемый порог очень изменчив. Если я останусь на безопасном уровне, будет извлечено правильное количество строк, а с другой стороны, будут извлечены нежелательные результаты.Как точно получить сегменты линии от проекционного участка?

Например вот это изображение:

enter image description here

И его горизонтальная проекция:

enter image description here

А вот код, я использую для извлечения строк текста:

%complementing as text must be non zero and background should be 0 
img_comp = imcomplement(img); 

%calculate the horizontal projections and plot it to verify the threshold 
horizontal_projections = sum(img_comp, 2); 
plot(horizontal_projections) 

%A very crude method of automatically detecting the threshold 

proj_mean = mean(horizontal_projections); 
lines = horizontal_projections > floor(proj_mean); 

% Find Rising and falling edges 
d = diff(lines); 
startingColumns = find(d>0); 
endingColumns = find(d<0); 

% Extract each line and save it in a cell 
for lines_k = 1 : length(startingColumns) 
    lines_extracted{lines_k} = img(startingColumns(lines_k):endingColumns(lines_k), :); 
end 

Я хочу автоматизировать выбор порога, но у меня возникают проблемы, если я использую порог, показанный в моем коде, который является средним значением прогнозов, он извлекает 9 строк, которые являются правильными, но линии теряют много данных, как в:

enter image description here

Это вторая линия, расширители и спусковые писем были отрезаны. Использование половины среднего или третьего из них работает, но оно отличается для каждого изображения и не автоматизирует его вообще.

ответ

1

Как насчет преобразования в цветовое пространство YCbCr? Использование формулы преобразования из Википедии.

img = im2double(imread('StackOverflow-Example.jpg')); 
rp = img(:, :, 1)/255 ; 
bp = img(:, :, 2)/255 ; 
gp = img(:, :, 3)/255 ; 
kb = 0.114; 
kr = 0.299; 
y = kr * rp + (1 - kr - kb) * gp + kb * bp; 
y = max(max(y))-y; 
y = y ./ y; 
surf(y,'EdgeColor','none','LineStyle','none') 
view(0, -90) 

Похоже, что это хорошая работа по поддержанию информации.

Edit:

Я думаю, что вы хотите, чтобы каждой линию

%% Load image and find intensity %% 
img = im2double(imread('test.jpg')); % load image and convert to doubles to allow for calculations 
rp = img(:, :, 1)/255 ; % normalized red portion 
bp = img(:, :, 2)/255 ; % normalized blue portion 
gp = img(:, :, 3)/255 ; % normalized green portion 
kb = 0.114; % blue constant from Wikipedia 
kr = 0.299; % red constant from Wikipedia 
x = kr * rp + (1 - kr - kb) * gp + kb * bp; % normalized intensity in image 
x = max(max(x))-x; % removed background 

y = x ./ x; % everything left is high 

z = y; 
z(isnan(y)) = 0; % turn nan's to zero 
divisions = find(sum(z,2) > 5); % find all lines that have less than 5 pixels 
divisions = [divisions(1); divisions(diff(divisions) > 10); size(z, 1)]; % find the line breaks 

rows = cell(length(divisions), 1); 

for i = 1:numel(rows)-1 
    line = z(divisions(i):divisions(i+1), :); % grab line 
    j = divisions(i) + find(sum(line,2) > 5) - 1; % remove the white space 
    line = y(j, :); 
    rows{i} = line; %store the line 
end 

rows(numel(rows)) = []; 

%% plot each line %% 
for i = 1:numel(rows) ; 
    figure(i) ; 
    surf(rows{i},'EdgeColor','none','LineStyle','none'); 
    view(0, -90) ; 
end 

%% plot entire page %% 
figure(numel(rows) + 1) 
surf(y,'EdgeColor','none','LineStyle','none') % plot of entire image 
view(0, -90) 

Edit: 2015/05/18 15:45 GMT

Это имеет значение для интенсивности оставшегося в:

img = im2double(imread('test.jpg')); 
rp = img(:, :, 1)/255 ; 
bp = img(:, :, 2)/255 ; 
gp = img(:, :, 3)/255 ; 
kb = 0.114; 
kr = 0.299; 
x = kr * rp + (1 - kr - kb) * gp + kb * bp; 
x = max(max(x))-x; 
xp = x; 
xp(xp == min(min(xp))) = nan; 

y = x ./ x; 

z = y; 
z(isnan(y)) = 0; 
divisions = find(sum(z,2) > 5); 
divisions = [divisions(1); divisions(diff(divisions) > 10); size(z, 1)]; 

rows = cell(length(divisions) - 1, 1); 

for i = 1:numel(rows) 
    line = z(divisions(i):divisions(i+1), :); 
    j = divisions(i) + find(sum(line,2) > 5) - 1; 
    line = xp(j, :); 
    rows{i} = line; 

    figure(i) ; 
    surf(rows{i},'EdgeColor','none','LineStyle','none'); 
    axis('equal') 
    view(0, -90) ; 
end 

figure(numel(rows) + 1) 
surf(xp,'EdgeColor','none','LineStyle','none') 
axis('equal') 
view(0, -90) 

Редактировать 2 015-05-22 13:21 GMT

%Turn warning message off 
warning('off', 'Images:initSize:adjustingMag'); 

%Read in image in int8 
originalImg = imread('test.jpg'); 

%Convert to double 
img = im2double(originalImg); 

%Take R, G, & B components 
rp = img(:, :, 1) ; 
gp = img(:, :, 2) ; 
bp = img(:, :, 3) ; 

%Get intensity 
kb = 0.114; 
kr = 0.299; 
yp = kr * rp + (1 - kr - kb) * gp + kb * bp; 

%Flip to opposite of intensity 
ypp = max(max(yp))-yp; 

%Normalize flipped intensity 
z = ypp ./ ypp; 
z(isnan(z)) = 0; 

%Find lines, this may need to be tuned 
MaxPixelsPerLine = 5; 
MinRowsPerLine = 10; 
divisions = find(sum(z,2) > MaxPixelsPerLine); 
divisions = [divisions(1); divisions(diff(divisions) > MinRowsPerLine); size(z, 1)]; 

%Preallocate for number of lines 
colorRows = cell(length(divisions) - 1, 1); 

for i = 1:numel(rows) 
    %Extract the lines in RGB 
    line = z(divisions(i):divisions(i+1), :); 
    j = divisions(i) + find(sum(line,2) > 5) - 1; 
    colorRows{i} = originalImg(j, :, :); 

    %Print out the line 
    figure(i) ; 
    imshow(colorRows{i}) 
end 

%Print out the oringinal image 
figure(numel(rows) + 1) 
imshow(originalImg) 

%Turn the warning back on 
warning('on', 'Images:initSize:adjustingMag'); 
+0

Вы могли бы также попытаться увеличить контраст. – mprat

+0

Спасибо. Кажется, это работает отлично. Но я не понимаю, что происходит. Не могли бы вы немного прокомментировать свой код. Кроме того, даже если '' surf'' отображает линии отдельно, можно ли использовать эту информацию для извлечения исходных строк из исходного изображения? Спасибо – StuckInPhD

+1

Отдельные строки хранятся в строках. Я также добавил несколько замечаний. – user1543042

1

Short: graythresh (IMG) migth решить вашу проблему

Longer:

С некоторым морфологическим Methodes, вы можете извлечь строки довольно легко. Небольшой недостаток: они несколько не в порядке.

загрузить ваше изображение

original = imread('o6WEN.jpg'); 

сделать это в оттенках серого

img=rgb2gray(original); . 

образуют прямоугольное структурный элемент с примерно TextHeight и 'очень' длинные

se = strel('rectangle',[30 200]); 

профильтровать с точечный фильтр. После этого будут видны длинные прямоугольные формы с около textheight.

img = imtophat(img,se); 

Регулировка контрастности:

img = imadjust(img); 

определить другой структурный элемент, на этот раз линии немного короче, чем TextHeight:

се = Стрел ('линии', 20,0);

Разбавить картину с его, чтобы избавиться от presisting GAPPS между буквами

img = imdilate(img,se); 

макияжем изображения в черно-с:

img=im2bw(img,graythresh(img)); 

используют regionprops, чтобы получить все BoundingBoxes образуют свои линии

stats=regionprops(img,'BoundingBox'); 
figure, imshow(img) 

В Stats теперь находятся ограничивающие коробки из всех ваших линий, s adly не по порядку. Возможно, это может быть исправлено с помощью BWlables или некоторой корреляции. Я просто посмотрел на y-Koordinates из BoundingBoxes и отсортировал их соответственно.

BoundingBoxes=struct2cell(stats); 
BoundingBoxes=cell2mat(BoundingBoxes'); % making it into an array 
[~,ind]=sort(BoundingBoxes(:,2)); % sorting it to y 
BoundingBoxes=BoundingBoxes(ind,:); % apply the sorted vector 

lineNr=8; 
imshow(original(BoundingBoxes(2,lineNr):BoundingBoxes(2,lineNr)+BoundingBoxes(4,lineNr),BoundingBoxes(1,lineNr):BoundingBoxes(1,lineNr)+BoundingBoxes(3,lineNr) )) 

надежда, что работает для вас

+0

Спасибо. Можете ли вы прокомментировать, что является целью '' lineNr''? и почему он установлен на 8? также в вашем коде, в котором дается ошибка '' index превышает размеры матрицы'' в последней строке '' imshow'', спасибо – StuckInPhD

+0

Последние две строки - это просто отобразить некоторую строку, здесь Nr 8, и продемонстрировать, как получить imge отдельной строки, вы можете удалить ее. –

+0

Правильно, спасибо.Итак, где координаты каждой линии? Приказ не имеет значения для меня, поэтому, если я хочу извлечь отдельные строки из исходного изображения, должен ли я использовать данные в '' BoundingBoxes''? Спасибо – StuckInPhD

Смежные вопросы