Images are rotated counter clockwise without any reason,

12 次查看(过去 30 天)
Hi,
So, I'm working on a code where I have a folder with 33 images and they are of different orientation (mix of landscape and portrait sizes). I have the script that reads the images from the folder and overlay gaze data on top of these images. The script is running fine except a small bug that im facing is that for final plot of 33 images, some images that are actually portrait size (elongated top to bottom) are plotted with counter clock-wise rotation to show it as a landscape.
The two images below are for reference. where Img x025 is correct plotted with right data but Img x033 is incorrect and its rotated and therefore the gaze data is correct but due to rotation, its not overlaid correctly.
I want the x033 image to look like this below and there are about 12-14 images that are displayed or showed in this way with wrong orientation:
The code is as follows, which is part of a larger script:
imageDir = 'C:\Users\mqs6680\Downloads\saliency-master\images1';
% Load the data
filename = 'DD2.tsv';
opts = detectImportOptions(filename, 'FileType', 'text');
data = readtable(filename, opts);
% Get unique participants
participants = unique(data.('ParticipantName'));
% Initialize a structure for participants
participantData = struct();
% Get a list of all JPG files in the folder
imageFiles = dir(fullfile(imageDir, '*.jpg'));
participantNames = fieldnames(participantData);
% Prompt user to enter a participant name or choose from a list
disp('Available participants:');
disp(participantNames);
selectedParticipant = input('Enter the name of the participant to plot (case-sensitive): ', 's');
% Check if the entered participant name is valid
if isfield(participantData, selectedParticipant)
% Get all images for the selected participant
imageNames = fieldnames(participantData.(selectedParticipant));
for j = 1:length(imageNames)
imageName = imageNames{j};
imageData = participantData.(selectedParticipant).(imageName);
% Ensure data exists for plotting
if ~isempty(imageData)
actualFixationX = imageData.ActualFixationX;
actualFixationY = imageData.ActualFixationY;
% Read the image from the file
imagePath = fullfile('C:\Users\mqs6680\Downloads\saliency-master\images', strcat(imageName, '.jpg')); % Assumes image extension is jpg
img = imread(imagePath);
% Check if the image needs to be rotated (portrait orientation)
if size(img, 1) > size(img, 2)
img = imrotate(img, -90); % Rotate the image clockwise by 90 degrees
% Correctly swap and calculate new fixation points
tempX = actualFixationX; % Temporary variable for swapping
actualFixationX = actualFixationY; % New X is the old Y
actualFixationY = size(img, 1) - tempX + 1; % New Y is adjusted based on the new image height
end
% Create a scatter plot on top of the image
figure; % Create a new figure for each image
imshow(img, 'InitialMagnification', 'fit'); % Display the image and fit it to the window
hold on; % Hold on to overlay scatter plot on the image
scatter(actualFixationX, actualFixationY, 'filled', 'r'); % Red points
hold off; % Release the hold to allow further plots to be displayed separately
title(sprintf('Fixation Points on Image for Participant: %s, Image: %s', selectedParticipant, imageName));
xlabel('Actual Fixation X (pixels)');
ylabel('Actual Fixation Y (pixels)');
end
end
else
fprintf('No data available for participant: %s\n', selectedParticipant);
end
Also, I have tried following different debugging methods:
Method 1:
% Check if the image needs to be rotated (portrait orientation)
if size(img, 1) > size(img, 2)
img = imrotate(img, -90); % Rotate the image clockwise by 90 degrees
% Swap X and Y fixation points for the rotated image
newFixationX = size(img, 1) - actualFixationY + 1; % Recalibrate to the new dimensions
newFixationY = actualFixationX;
actualFixationX = newFixationX;
actualFixationY = newFixationY;
end
Method 2:
% Check if the image needs to be rotated (portrait orientation)
if size(img, 1) > size(img, 2)
img = imrotate(img, -90); % Rotate the image clockwise by 90 degrees
% Swap X and Y fixation points for the rotated image
[actualFixationX, actualFixationY] = deal(actualFixationY, size(img, 2) - actualFixationX + 1);
end
I have cut portion of the code where it was handling the gaze data related stuff. Anyhelp will be appreciated. Thank you so much.
  1 个评论
Stephen23
Stephen23 2024-5-15
编辑:Stephen23 2024-5-15
@Muhammad Rakeh Saleem: please upload Img x025 and Img x033.
My guess is that you will find the file tranpose/rotation flag is set for some of those images. But IMREAD imports the raw image data, which is unaffected by that flag.

请先登录,再进行评论。

采纳的回答

DGM
DGM 2024-5-15
编辑:DGM 2024-5-15
Most JPG photos will have orientation metadata which will be completely ignored by imread(). You need to either manually rotate and flip each image according to the number in the metadata, or you need to use a tool that will do that job. In this post, I provide such a tool (see the attached imreadort.m
That should handle all of the typical 8 orientations used by modern cameras.
  5 个评论
Muhammad Rakeh Saleem
编辑:Muhammad Rakeh Saleem 2024-5-15
@DGM I think I was too excited to see the image flip cause it was frustrating. I totally omit the data points, and now that I inspect the gaze data points it turns out that all the images whose orientation was rotated and was fixed. The fixation data points on these images are skewed/ not overlay properly. Reference image 1 shows the output of MATLAB and reference Image 2 shows the actual results on the eye trakcing software.
Before code:
After code:
What I am hoping to get eventually:
The interesting part is that the skewness in the data points is applied to the images only that were not oriented correctly, and although the above code solved the orientation fix, the data points are off so im wondering if there is something happening in the code @DGM. Thanks again and I appreciated your help and response.
DGM
DGM 2024-5-15
编辑:DGM 2024-5-16
That's odd. It looks like it should be oriented correctly, but it's like the points were mapped into a distorted space.
I don't really know how those points were captured, but I have a suspicion that the mapping process didn't take into account how the image had been rotated when denormalizing. For example, the above image would have been displayed in a "tall" aspect ratio (e.g. 4000x3000), but the gaze points were mapped into a coordinate space which was derived from non-rotated height and width info from the metadata (e.g. 3000x4000).
% these points are correctly oriented (arrow points down-right)
% but they were mapped into the wrong geometry (wide)
% so it's not aligned to the wagon box
load pts.mat
inpict = imread('wagon.jpg');
sz0 = size(inpict,1:2);
% show the image with the distorted points
imshow(inpict,'border','tight'); hold on
plot(pts(:,1),pts(:,2),'linewidth',2)
% remap the points to the correct geometry
AR = sz0(1)/sz0(2);
correctedpts = pts.*[1/AR AR];
plot(correctedpts(:,1),correctedpts(:,2),'linewidth',2)
Something like that is what I'm guessing went on. Hard to say for sure when the mapping error occurred without seeing the data. You might want to double-check and make sure that the error is actually baked into the coordinates and isn't just being introduced during plotting based on stale geometry information.

请先登录,再进行评论。

更多回答(2 个)

Image Analyst
Image Analyst 2024-5-15
Many cameras have an "orientation" tag that says what orientation the camera was in when you took the photo. I believe it's either 1, 2, 3, or 4. So for example if you used your smartphone right side up or upside down, when it's displayed, if displayed by a program that reads the orientation flag, it will always show up rightside up. If it's a TIFF image you can read the orientation tag from the image file with imfinfo (See attached function) and rotate it as needed since evidently imread does not take the orientation into consideration.
% Read_Tiff_Header
% Reads in the header information from an .Tiff format Mayo Clinic data file
% and returns the information in a structure stHeader.
%
% Input:
% fullFileName - string, Full filename (including folder) of the Tiff file.
% Output:
% stHeader - Structure with these members, and example values shown below:
% FileModDate: '22-Oct-2007 15:57:24'
% FileSize: 17060
% Format: 'tif'
% FormatVersion: []
% Width: 1024
% Height: 841
% BitDepth: 8
% ColorType: 'grayscale'
% FormatSignature: [73 73 42 0]
% ByteOrder: 'little-endian'
% NewSubFileType: 0
% BitsPerSample: 8
% Compression: 'PackBits'
% PhotometricInterpretation: 'BlackIsZero'
% StripOffsets: [106x1 double]
% SamplesPerPixel: 1
% RowsPerStrip: 8
% StripByteCounts: [106x1 double]
% XResolution: 72
% YResolution: 72
% ResolutionUnit: 'Inch'
% Colormap: []
% PlanarConfiguration: 'Chunky'
% TileWidth: []
% TileLength: []
% TileOffsets: []
% TileByteCounts: []
% Orientation: 1
% FillOrder: 1
% GrayResponseUnit: 0.0100
% MaxSampleValue: 255
% MinSampleValue: 0
% Thresholding: 1
%
% stHeader includes everything in the Tiff header as returned by MATLAB via the imfinfo() function,
% shown above, and includes a few extra members (BytesPerVoxel and Depth).
% BytesPerVoxel - integer, typically 8 or 16
% Depth - integer, Z Dimension of the image
%
% Written by Mark Hayworth on 10/24/2007.
%------------------------------------------------------------------------------
function stHeader = Read_Tiff_Header(fullFileName, varargin)
% Check range of variables.
%disp([num2str(nargin) ' arguments passed in, because nargin = ' num2str(nargin) '.']);
% Need to have either 1 or 2 arguments.
if (nargin < 1 || nargin > 2)
% Not 1 or 2 args.
error('Usage : stHeader = ReadTiffHeader(fullFileName, intDisplayHeaderInCommandWindow)');
else
% They passed in 1 or two args.
if (nargin == 1)
% If they didn't supply the intDisplayInCommandWindow argument, set it to zero.
intDisplayInCommandWindow = 0;
else
% Take what they passed in.
intDisplayInCommandWindow = varargin{1};
end
end
if (ischar(fullFileName) < 1)
error('Requires a string filename as an argument.');
end
% Use built-in MATLAB function to read the TIFF header.
stHeader = imfinfo(fullFileName);
%stHeader.BytesPerVoxel = stHeader.BitsPerSample / 8;
% stHeader.Depth = 1;
stHeader.x_size = stHeader.Width;
stHeader.y_size = stHeader.Height;
stHeader.z_size = 1;
% Display the values in the command window.
if (intDisplayInCommandWindow > 0)
message = sprintf('\nFull File Name = %s', fullFileName);
disp(message);
stHeader
end

Image Analyst
Image Analyst 2024-5-15
You can try this MATLAB function in the File Exchange to read EXIF tags:
There are also IPTC tags on some images but I don't know if that tool reads IPTC tags. I think there might be some overlap in that a tag in one might also be in the other but have a slightly different name for it, like headline, title, description, subject, etc.
EXIF tags are usually having to do with hardware/camera settings (like if the flash was used, F/stop, focal length, shutter speed, etc.)
IPTC tags are generally information about the or scene (like photographers or journalists might like) like who took the photo, who's in it, a title for it, who wrote the description for it, what country it was taken in, etc.
Wikipedia references:
A program like ACDSee will show you both types of tags and let you change/edit them.

产品

Community Treasure Hunt

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

Start Hunting!

Translated by