How to extract letters and increase background size without changing character size

2 次查看(过去 30 天)
I've got somewhat of a working OCR, it works for reading numbers, Uppercase and some lower case letters. I'm having trouble with lower case letters mostly because my character segmentation makes characters with similar strokes like the letter C/c and O/o read the as a capital letter.
The segmentation uses bounding boxes and afterwards gets patched with zeros on the left and right side to make it a square then gets resized to 28by28 pixels by a seperate for loop (for it to become usable with the EMNIST dataset I'm using). But it downscales the entire character and makes it look like the upper case version.
Basically I just want to make segment a character then make it 28x28 without changing the actual size of the character. I have a feeling it has something to do with how I segment the characters.
Should look lower case instead of upscaled one on the right
Here's the code I have right now followed by the rough function I made for the segmentation and the one I use to make it squared
% Part of the code I want to replace, it basically resizes lower case to look like upper case letters
item1resized = []; item2resized = [];
App.item1vec = []; App.item2vec = [];
% Resize everything to 28x28
for s1 = 1 : length(storeitem1)
[storeitemt1] = squarit(storeitem1{s1});
resized1 = imresize(storeitemt1,[28 28]);
item1resized{s1} = resized1;
end
% Function to segment the characters.
function [store,cent] = Segment(appim)
binim = imbinarize(appim);
box = regionprops(binim,'BoundingBox');
bd = [box];
coor = [];
cent=[];
%%
store = {};
for k = 1 : length(box)
BB = box(k).BoundingBox;
coor{k} = BB;
st = imcrop(appim,[BB(1),BB(2),BB(3),BB(4)]);
sz = size(st);
if (sz(1) < 250) && (sz(2) < 250) && sz(1) > 4 && sz(2) > 4
store{k} = st;
end
end
% Function to patch up sides to make it a square. Pretty much a bruteforce way of making it compatible with EMNIST
function [storeitemt] = squarit(st)
[m,n] = size(st);
if m > n
x = m-n;
storeitemt = [zeros(m,floor(x/2)) st zeros(m,floor(x/2))];
elseif m < n
storeitemt = [zeros(floor(n/3),n); st; zeros(floor(n/3),n)];
elseif m==n
storeitemt = st;
end
end

回答(1 个)

Ayush
Ayush 2023-11-17
Hi Jacob,
I understand that you want to segment a character then make it 28x28 without changing the actual size of the character.
You can try to use padding directly for your image instead of resizing the entire character first, this way you can preserve the aspect ratio of the characters while making the size to 28x28. You can use the MATLAB function “padarray” which will help you in adding 0’s to make the image 28x28 without affecting aspect ratio of the character. Refer the pseudo code below for better understanding:
% Pad to 28x28
for s1 = 1 : length(storeitem1)
[storeitemt1] = squarit(storeitem1{s1});
resized1 = padto28x28(storeitemt1);
item1resized{s1} = resized1;
end
% Function to pad the character image to 28x28
function [paddedImage] = padto28x28(image)
[m, n] = size(image);
maxDim = max(m, n);
padSize = maxDim - min(m, n);
% Determine padding sizes
padTop = floor(padSize / 2);
padBottom = ceil(padSize / 2);
padLeft = floor((maxDim - n) / 2);
padRight = ceil((maxDim - n) / 2);
% Pad the image
paddedImage = padarray(image, [padTop padLeft], 0, 'pre');
paddedImage = padarray(paddedImage, [padBottom padRight], 0, 'post');
% Resize to 28x28 if necessary
if maxDim > 28
paddedImage = imresize(paddedImage, [28 28]);
end
You can refer the link below for more information on “padarray” function:
Regards,
Ayush

类别

Help CenterFile Exchange 中查找有关 Images 的更多信息

产品


版本

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by