find Center pixel to maximum distance

25 views (last 30 days)
waheed on 24 Jul 2020
Answered: DGM on 22 Jan 2023
Calculate the center pixel of the image and the maximum distance (M) possible from the center to any corner

Answers (3)

KALYAN ACHARJYA on 24 Jul 2020
Edited: KALYAN ACHARJYA on 24 Jul 2020
The position of the pixel is [round(r/2),round(c/2)], now calculate the euclidean distance in any direction
  1 Comment
Walter Roberson
Walter Roberson on 24 Jul 2020
For the purpose of the calculation that the user is doing, you should not round() the coordinates of the center.
The user is working with RGB images, so

Sign in to comment.

Image Analyst
Image Analyst on 24 Jul 2020
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);
% Corrected code:
rgbImage = imread('flower.jpg');
rgbImage = imread('peppers.png');
[rows, columns, numberOfColorChannels] = size(rgbImage)
subplot(2, 2, 1);
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);
subplot(2, 2, 2);
imshow(distanceImage, []);
yline(yMid, 'Color', 'b', 'LineWidth', 2);
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);
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 on 22 Jan 2023
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');
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