Remove pixel whose value is below given threshold

15 Ansichten (letzte 30 Tage)
MatlabEnthusiast
MatlabEnthusiast am 2 Mär. 2022
Kommentiert: MatlabEnthusiast am 2 Mär. 2022
Hello, how can i remove pixels from an image whose values are below/above a given threshold value? As far as I know images in MATLAB are rectangular. So is this even possible? How most efficiently can this be achieved, or something close to this?
Say I have an image A, my threshold is 4. So i want ot remove A(i,j) <= 4 .
I looked at this post, but i think the title is a bit misleading, they are more like changing the value of the pixel. I want total removal/deletion if possible. So in the end i expect the resulting/output image to have different dimensions from the original input. So its more like customized croping.
Thank you very much.
  5 Kommentare
DGM
DGM am 2 Mär. 2022
If some sort of best-fit box approach were implemented, would it be acceptable for some of the bad pixels to be left if it would allow for local content preservation? On the other hand, would it be acceptable to discard some good pixels?
Would it be better to keep the image rigid, or would some amount of shearing be acceptable? Using reshape() tends to progressively displace content, but a vectorwise approach may be less destructive:
% get a basic test image
A = imread('cameraman.tif');
A = A*0.7 + 0.3*255;
s = size(A);
% same noisy image
B3 = A;
idx = randi([1 prod(s)],1,1000);
B3(idx) = 0;
imshow(B3)
C = zeros(s,'uint8');
for col = 1:s(2)
thisvec = B3(:,col);
thisvec = thisvec(thisvec~=0); % select only good pixels
C(1:numel(thisvec),col) = thisvec;
end
imshow(C)
At which point, you could choose to crop off as much of the bottom of the image as you need (again, the remark about whether it's okay to leave bad pixels or discard good pixels). Similar can obviously be done on rows.
DGM
DGM am 2 Mär. 2022
Regarding a fit-box and preserving some bad pixels:
% get a basic test image
A = imread('cameraman.tif');
A = A*0.7 + 0.3*255;
s = size(A);
% generate a noisy image
% this uses MIMT tools, so ignore that.
BG = zeros(s,'uint8');
alph = radgrad(s,[0.5 0.5],0.5,[255;0],'cosine','uint8') + 100;
FG = cat(3,A,alph);
B = imblend(FG,BG,1,'normal',1,'dissolvezf');
B = B(:,:,1);
% obviously i can't use MIMT here, so i just attached B
% B = imread('noisyb.png');
imshow(B)
% try to find some sort of mask that describes the least-noisy region
mask = B~=0;
mask = imopen(mask,strel('disk',20,0));
imshow(mask)
% find the extents of the blob and crop the image to it
S = regionprops(mask,'boundingbox');
C = imcrop(B,S.BoundingBox);
imshow(C)

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Matt J
Matt J am 2 Mär. 2022
Bearbeitet: Matt J am 2 Mär. 2022
It is possible to do, but only when the pattern that remains is a rectangular sub-image, e.g.,
A =[1 1 1 1;
1 6 1 6;
2 5 2 5;
3 3 3 3]
A = 4×4
1 1 1 1 1 6 1 6 2 5 2 5 3 3 3 3
map=A<=4;
I=all(map,2); J=all(map,1);
A(I,:)=[]; A(:,J)=[];
A
A = 2×2
6 6 5 5
  5 Kommentare
Matt J
Matt J am 2 Mär. 2022
You're welcome, but if your question has been answered, please Accept-click the answer that best addressed it.
MatlabEnthusiast
MatlabEnthusiast am 2 Mär. 2022
@Matt J, yeah I will accept ofcourse but there's alot of new information for me. Am going to try them out for different cases then ofcourse i will accept an answer. Thank you guys for all these awesome suggestions.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (3)

DGM
DGM am 2 Mär. 2022
If you're trying to automatically crop borders off an image, you might be able to use the comments from ImageAnalyst and myself on this thread:
I give a comparison of a few different methods.

DGM
DGM am 2 Mär. 2022
Bearbeitet: DGM am 2 Mär. 2022
Alternatively, this is an extension from my comment above. If image content preservation is not important, the images can be reshaped. I'm not sure why this would be necessary though. In most cases, I assume that it would suffice to simply vectorize the image instead.
A = imread('cameraman.tif');
A = A*0.7 + 0.3*255;
s = size(A);
% central black region
B2 = A;
B2(100:end-100,100:end-100) = 0;
% find bad pixels and reshape to the most-square geometry possible
mask = B2~=0;
goodpx = nnz(mask);
npf = factor2(goodpx,'ordered',false);
B2r = reshape(B2(mask),npf(end,:));
imshow(B2r)
% random pixel locations
B3 = A;
idx = randi([1 prod(s)],1,500);
B3(idx) = 0;
% find bad pixels and reshape to the most-square geometry possible
mask = B3~=0;
goodpx = nnz(mask);
npf = factor2(goodpx,'ordered',false);
B3r = reshape(B3(mask),npf(end,:));
imshow(B3r)
Attached is the tool used for finding candidate geometries.

DGM
DGM am 2 Mär. 2022
Here's another silly answer based on my last two comments. In this case, we're accepting minor local distortion in order to sift the pixels toward the least-noisy region in order facilitate subsequent cropping. This really would only work well in cases where the noise density is largely non-convex. In the example with a square hole in the middle of the image, the distortion would be significantly increased.
% % get a basic test image
% A = imread('cameraman.tif');
% A = A*0.7 + 0.3*255;
% s = size(A);
%
% % generate a noisy image
% % this uses MIMT tools, so ignore that.
% BG = zeros(s,'uint8');
% alph = radgrad(s,[0.5 0.5],0.5,[255;0],'cosine','uint8') + 100;
% FG = cat(3,A,alph);
% B = imblend(FG,BG,1,'normal',1,'dissolvezf');
% B = B(:,:,1);
% obviously i can't use MIMT here, so i just attached B
B = imread('noisyb.png');
s = size(B);
imshow(B)
% create a mask that describes the least-noisy region
mask = B~=0;
mask = imopen(mask,strel('disk',20,0));
mask = bwareafilt(mask,1);
imshow(mask)
% find center
S = regionprops(mask,'centroid');
cen = round(S.Centroid); % center of good region
% sift radially toward the center
for d = 1:4
for c = 2:s(1)-1
linemask = logical(xwline(s,[cen(1) 1],[cen(2) c])); % create a mask
sampvec = B(linemask); % sample B along that line
outvec = zeros(size(sampvec),'uint8'); % allocate
sampvec = sampvec(sampvec~=0); % only get good pixels
outvec(end-numel(sampvec)+1:end) = sampvec; % sift vector
B(linemask) = outvec; % replace
end
B = rot90(B);
s = size(B);
end
imshow(B)
At this point, it's up to the user to decide whether to crop off all the bad pixels (discarding some good pixels) or do crop only bad pixels (keeping some bad pixels).
This is probably a hilariously inefficient way to do this, but consider it a proof of concept.

Kategorien

Mehr zu Get Started with Image Processing Toolbox finden Sie in Help Center und File Exchange

Produkte


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by