Segmented blur fails when adding segments on image
1 回表示 (過去 30 日間)
古いコメントを表示
I have an image and I have an focus (rectangular) area which will be clear in result. I need to find another rectangular area larger than focus area. First keep focus area and other found area in a variable to user later. Now blur whole image much and then blur another area we found less than whole image and put it back. At last, put the focus back on image. What is wrong with my code?
Input Image
result image
x1,y1,x2,y2 are retes of coordinates. if x1 = 0.1 on 1020 pixel image x = 102
function blurred_image = blurImage(image, x1, y1, x2, y2)
[height, width, ~] = size(image);
%desired area coordinates
c_x1 = floor(width * x1);
c_y1 = floor(height * (1-y1));
c_x2 = floor(width * x2);
c_y2 = floor(height * (1-y2));
%blurred segment
b_x1 = floor(abs(c_x1 - c_x1/2));
b_y1 = floor(abs(c_y1 - c_y1/2));
b_x2 = floor(abs(c_x2 + (width - c_x2)/2));
b_y2 = floor(abs(c_y2 + (height - c_y2)/2));
fprintf("%d\n", b_x1);
fprintf("%d\n", b_y1);
fprintf("%d\n", b_x2);
fprintf("%d\n", b_y2);
focus = image(c_y1:c_y2, c_x1:c_x2);
segment = imgaussfilt(image(b_y1:b_y2,b_x1:b_x2), 3);
image = imgaussfilt(image, 5);
image(b_y1:b_y2, b_x1:b_x2) = segment;
image(c_y1:c_y2, c_x1:c_x2) = focus;
blurred_image = image;
end
回答 (2 件)
Pranjal Kaura
2021 年 7 月 27 日
編集済み: Pranjal Kaura
2021 年 7 月 27 日
Hey,
It is my understanding that you want to develop a function using which you can focus on a certain part of the image by blurring other parts. You want to blur the image in segments to achieve a gradient look in the output.
The problem with your code is
- You’re using a 3D image with imgausfilt function, which is a 2D image smoothing function. If you want to use 3D images, you can use imgausfilt3 function.
- The extracted co-ordinates (c_y1, c_y2) are incorrect and [b_x1, b_y1] had overhead calculations which can be optimised.
Here’s a code snippet that might be helpful
img = rgb2gray(imread('img.jpeg'));
imshow(img);
title("Input Image");
figure;
out_img = blurImage(img, 0.55, 0.1, 0.85, 0.8);
imshow(out_img);
title("Output Image");
function blurred_image = blurImage(image, x1, y1, x2, y2)
[height, width, ~] = size(image);
%desired area coordinates
c_x1 = floor(width * x1);
c_y1 = floor(height * y1);
c_x2 = floor(width * x2);
c_y2 = floor(height * y2);
%blurred segment
b_x1 = floor(abs(c_x1/2));
b_y1 = floor(abs(c_y1/2));
b_x2 = floor(abs(c_x2 + (width - c_x2)/2));
b_y2 = floor(abs(c_y2 + (height - c_y2)/2));
fprintf("%d %d\n", b_x1, c_x1);
fprintf("%d %d\n", b_y1, c_y1);
fprintf("%d %d\n", b_x2, c_x2);
fprintf("%d %d\n", b_y2, c_y2);
focus = image(c_y1:c_y2, c_x1:c_x2);
segment = imgaussfilt(image(b_y1:b_y2,b_x1:b_x2), 5);
image = imgaussfilt(image, 9);
image(b_y1:b_y2, b_x1:b_x2) = segment;
image(c_y1:c_y2, c_x1:c_x2) = focus;
blurred_image = image;
end
0 件のコメント
DGM
2024 年 10 月 1 日
編集済み: DGM
2024 年 10 月 1 日
This is closer to how I'd do it. This is easier to use, it's not restricted to single-channel images, and it correctly handles cases where the sample region meets the edge of the image.
inpict = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/239743/img.jpeg');
points = [0.1, 0.1; 0.75, 0.5];
sig = [20 5]; % i'm being extreme so it shows up on the forum
outpict = blurImage(inpict,points,sig);
imshow(outpict)
function outpict = blurImage(inpict,points,sig)
% INPICT is a I/IA/RGB/RGBA image of any standard image class.
% POINTS is a 2x2 array specifying the corners of the rectangular selection.
% The form is [x1 y1; x2 y2].
% The units are normalized with respect to the image geometry.
% SIG is a 2-element vector specifying the sigma parameter for the
% filter passes [exterior region, margin region]
%
% use arrays instead of confusing drifts of loose scalars
% clamp pointlist on input when it's in normalized coordinates
% sort pointlist so that we get the same rectangle
% regardless of which two vertices we were given
sz = size(inpict,1:2);
points = min(max(points,0),1);
points = sort(points,1);
points = cat(3,[points(1,:)/2; 1-(1-points(2,:))/2],points);
% convert to subscripts
% scaling from zero will cause errors; think about why.
pc = floor(1 + fliplr(points).*(sz - 1));
% compose the image
outpict = imgaussfilt(inpict,sig(1));
for k = 1:2
xsubs = pc(1,2,k):pc(2,2,k);
ysubs = pc(1,1,k):pc(2,1,k);
if k == 1
sample = inpict(ysubs,xsubs,:);
outpict(ysubs,xsubs,:) = imgaussfilt(sample,sig(2));
else
outpict(ysubs,xsubs,:) = inpict(ysubs,xsubs,:);
end
end
end
0 件のコメント
参考
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!