I have a white/black image. I want to apply Gaussian filter to the white pixels on this image. However, I want to apply it pixel by pixel as I want to give different Gaussian bandwidth parameters to different pixels.
For example, there are only 2 pixels on an image are white, others are black. I want to apply different Gaussian filter to these 2 pixels. Let's say X[2] and Y[2] are coordinates of the 2 pixels.
Gaussian bandwidth for X[0] and Y[0] is [10, 10], standard deviation is 1.
Gaussian bandwidth for X[1] and Y[1] is [20, 20], standard deviation is 3.
I know roifilt2 would work on ROI, but it seems that it only applies to an area of the image not a single pixel. I have coded by my understanding after I checked ROI processing, but the code below gives me error:
Error using imwrite (line 422)
Image data can not be empty.
Error in guassianFilter (line 73)
imwrite(out,[outdir,imname,'.png'],'png');
It seems the filtered output image is empty. But I am new to matlab, I don't know why this is happening and how to fix it. :(
Is there any matlab functions that I can directly call to do the job?
Code:
while ischar(tline)
line = regexp(tline,' ','split');
if(strcmp(line{1},'touch') == 1)
c = floor(str2double(line{1,3})); % same as X[0] as I mentioned above
r = floor(str2double(line{1,4})); % same as Y[0] as I mentioned above
BW = roipoly(im,c,r);
G = fspecial('gaussian',[10 10],1);
out = roifilt2(G,im,BW);
end
if(strcmp(line{1},'dT') == 1)
c = floor(str2double(line{1,3})); % same as X[1] as I mentioned above
r = floor(str2double(line{1,4})); % same as X[1] as I mentioned above
BW = roipoly(im,c,r);
G = fspecial('gaussian',[20 20], 3);
out = roifilt2(G,im,BW);
end
tline = fgets(fid);
end
fclose(fid);
imname=strtok(imList(cnt).name,'.');
imwrite(out,[outdir,imname,'.png'],'png');
Before outlining an idea that should work, let me observe one problem with the code you posted. Looking at your calls to roifilt2
you see that out
is overwritten with the result of each single-pixel instruction that you read from file. Even if you spotted some other bug that results in an empty result image, the result would never be the composite.
How about this. You could first read all the pixel positions and corresponding bandwidths from file, and then reconstruct the filtered image in two strokes from these coordinates alone. Reading the pixel list could look like this
fid = fopen('points.txt');
pxl = struct('x', {}, 'y', {}, 'sig', {});
n_pxl = 0;
tline = fgets(fid);
while ischar(tline)
line = regexp(tline,' ','split');
n_pxl = n_pxl + 1;
pxl(n_pxl).x = floor(str2double(line{1,3}));
pxl(n_pxl).y = floor(str2double(line{1,4}));
if strcmp(line{1},'touch') == 1
pxl(n_pxl).sig = 1;
elseif strcmp(line{1},'dT') == 1
pxl(n_pxl).sig = 3;
else
pxl(n_pxl).sig = nan;
end
tline = fgets(fid);
end
fclose(fid);
where x
and y
are the positions and sig
is the bandwidth. Assuming that WIDTH
and HEIGHT
are the dimensions of your image, you could initialize the composite result image to flat out = zeros(HEIGHT, WIDTH);
. A lookup vector for your filter sizes could be flt_size = [10, 15, 20];
. In some for
-loop over sig = [1, 3]
, we create each "slide" of the overlay, after collecting all the pixels corresponding to a particular sigma
im_raw = zeros(HEIGHT, WIDTH);
for k = find([pxl.sig] == sig)
im_raw(pxl(k).y, pxl(k).x) = 1;
end
and increment the composite with the result of the filter operation
fsz = flt_size(sig);
out = out + conv2(im_raw, fspecial('gaussian', [fsz, fsz], sig), 'same');
Taken together, the loop would could like this:
out = zeros(HEIGHT, WIDTH);
flt_size = [10, 15, 20];
for sig = [1, 3]
im_raw = zeros(HEIGHT, WIDTH);
for k = find([pxl.sig] == sig)
im_raw(pxl(k).y, pxl(k).x) = 1;
end
fsz = flt_size(sig);
out = out + conv2(im_raw, fspecial('gaussian', [fsz, fsz], sig), 'same');
end
Using slightly larger bandwidth for illustration, here an example, for two points in each category. The left and middle image show each "slide", and the right image shows the composite. Each image is shown scaled by imagesc
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.