find Center pixel to maximum distance

11 次查看(过去 30 天)
waheed
waheed 2020-7-24
回答: DGM 2023-1-22
Calculate the center pixel of the image and the maximum distance (M) possible from the center to any corner

回答(3 个)

KALYAN ACHARJYA
KALYAN ACHARJYA 2020-7-24
编辑:KALYAN ACHARJYA 2020-7-24
[r,c]=size(image);
centre_pix=image(round(r/2),round(c/2));
The position of the pixel is [round(r/2),round(c/2)], now calculate the euclidean distance in any direction
  1 个评论
Walter Roberson
Walter Roberson 2020-7-24
For the purpose of the calculation that the user is doing, you should not round() the coordinates of the center.
[r,c]=size(image);
The user is working with RGB images, so
[r,c,p]=size(image);

请先登录,再进行评论。


Image Analyst
Image Analyst 2020-7-24
You can do this:
[x, y] = meshgrid(1:columns, 1:rows);
distanceImage = sqrt((x-columns/2).^2 + (y - rows/2).^2);
Here's a full demo (from your other question):
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
fprintf('Beginning to run %s.m ...\n', mfilename);
% Original, bad code from original poster.
% i=imread('flower.jpg')
% im=double(i)
% [x,y,z]=size(im);
% c=im(round(x/2),round(y/2));
% %pix_1 = [p11,p12];
% %pix_2 = [p21,p22];
% %distance = sqrt( (p21-p11)^2 + (p22-p12)^2 );
% distane=sqrt((x1-cx)^2 + (y1 - cy)^2)
% x1,y1 ar cx, cy er distance - sqrt((x1-cx)^2 + (y1 - cy)^2);
% 0 Comments
% Corrected code:
rgbImage = imread('flower.jpg');
rgbImage = imread('peppers.png');
[rows, columns, numberOfColorChannels] = size(rgbImage)
subplot(2, 2, 1);
imshow(rgbImage);
impixelinfo;
title('Original Color Image', 'FontSize', 20);
axis('on', 'image');
% Get vignetting pattern (not really, this is not the right formula, but let's just pretend this function is it).
[x, y] = meshgrid(1:columns, 1:rows);
distanceImage = sqrt((x-columns/2).^2 + (y - rows/2).^2);
% Normalize to a percentage so it's in the 0-1 range:
distanceImage = 1 - distanceImage / max(distanceImage(:));
% Get a profile through the middle and plot it.
yMid = int32(rows/2);
horizontalProfile = distanceImage(yMid, :);
subplot(2, 2, 3);
plot(horizontalProfile, 'b-', 'LineWidth', 2);
title('Horizontal Profile', 'FontSize', 20);
xlabel('Column', 'FontSize', 20);
ylabel('Attenuation Factor', 'FontSize', 20);
grid on;
% Convert to color
if numberOfColorChannels == 3
distanceImage = cat(3, distanceImage, distanceImage, distanceImage);
end
subplot(2, 2, 2);
imshow(distanceImage, []);
yline(yMid, 'Color', 'b', 'LineWidth', 2);
impixelinfo;
axis('on', 'image');
title('Distance Image', 'FontSize', 20);
% Multiply the images together.
outputImage = uint8(distanceImage .* double(rgbImage));
subplot(2, 2, 4);
imshow(outputImage, []);
axis('on', 'image');
title('Output Image', 'FontSize', 20);
impixelinfo;
Note that the horizontal profile is the linear distance of a pixel away from the middle. Actually it's from the half column. So if your image had 10 columns, it's the distance from 5, not 5.5 (which would be in between the two "middle" columns), so you can easily modify the code if you want that.

DGM
DGM 2023-1-22
I'm going to ignore how to calculate the distance array, and just focus on the task that the tagging implies. If the goal is to add a vingetting effect to an image, then it can be very simple if you use third-party tools.
MIMT radgrad() generates radial gradients given three geometry parameters: the image height and width, the center in normalized coordinates, and the radius, normalized to the image diagonal. If the goal is to create a gradient which starts at the image center and extends to the corners, then specify [0.5 0.5] for the center and 0.5 for the radius. No need to do any math.
While a multiply blend is one of the simplest types of image blending operations, if one wants to simply multiply two image arrays, care must be paid to make sure that the class and depth of the two arrays match. MIMT imblend() can perform image blending between images of compatible geometry, regardless of their class or number of color channels. If you want something more complicated than 'multiply', imblend() has those too.
% an image
BG = imread('peppers.png'); % 3 channels (RGB)
% a radial gradient with linear ease curve
% this is not the distance, but _proportional_ to the distance
% the exact distance likely doesn't matter in this application
% the goal is that attenuation is a _function_ of distance.
FG = radgrad(size(BG),[0.5 0.5],0.5,[255; 0],'linear'); % 1 channel
% generate the output image by image blending
outpict = imblend(FG,BG,1,'multiply');
imshow(outpict)
Bear in mind that a simple two-point radial gradient with a linear ease curve is often not the best thing to use. While radgrad() supports nonlinear ease curves, you can always change the shape of the ease curve using imadjust(). Here, the center of the gradient is flattened, making a broader region which is not darkened. Adjusting gamma makes the transition less noticeable.
% ...
FG = imadjust(FG,[0 0.9],[0 1],0.5); % adjust ease curve
% ... and then blend as before
Two or three lines is a lot easier to write, and it's a lot simpler than trying to correctly handle changes to the image geometry, depth, or class.

标签

Community Treasure Hunt

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

Start Hunting!

Translated by