63 views (last 30 days)
Show older comments
Muhammad Rakeh Saleem on 15 May 2024 at 16:03
-
-
Link
Direct link to this question
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason
Edited: DGM on 16 May 2024 at 8:19
Accepted Answer: DGM
Open in MATLAB Online
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 Comment Show -1 older commentsHide -1 older comments
Show -1 older commentsHide -1 older comments
Stephen23 on 15 May 2024 at 17:04
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason#comment_3162281
Edited: Stephen23 on 15 May 2024 at 18:32
@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.
Sign in to comment.
Sign in to answer this question.
Accepted Answer
DGM on 15 May 2024 at 21:21
Edited: DGM on 15 May 2024 at 21:24
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
https://www.mathworks.com/matlabcentral/answers/392643-why-is-matlab-reading-some-images-in-rotated-by-90-degrees
That should handle all of the typical 8 orientations used by modern cameras.
5 Comments Show 3 older commentsHide 3 older comments
Show 3 older commentsHide 3 older comments
Image Analyst on 15 May 2024 at 21:39
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason#comment_3162601
@Muhammad Rakeh Saleem see his
https://www.mathworks.com/matlabcentral/fileexchange/53786-image-manipulation-toolbox?s_tid=srchtitle
it reads EXIF tags.
DGM on 15 May 2024 at 21:51
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason#comment_3162626
MIMT does have the full version of imreadort(), but I did attach a simplified version on the forum.
Muhammad Rakeh Saleem on 15 May 2024 at 22:42
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason#comment_3162641
Thanks @DGM, your answer was simple and quick. Works for me! Thanks
Muhammad Rakeh Saleem on 15 May 2024 at 23:05
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason#comment_3162651
Edited: Muhammad Rakeh Saleem on 15 May 2024 at 23:11
@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 on 15 May 2024 at 23:52
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2119216-images-are-rotated-counter-clockwise-without-any-reason#comment_3162666
Edited: DGM on 16 May 2024 at 8:19
Open in MATLAB Online
- pts.mat
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.
Sign in to comment.
More Answers (2)
Image Analyst on 15 May 2024 at 17:46
Open in MATLAB Online
- Read_Tiff_Header.m
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
0 Comments Show -2 older commentsHide -2 older comments
Show -2 older commentsHide -2 older comments
Sign in to comment.
Image Analyst on 15 May 2024 at 21:57
You can try this MATLAB function in the File Exchange to read EXIF tags:
https://www.mathworks.com/matlabcentral/fileexchange/42000-run_exiftool?s_tid=srchtitle
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.
0 Comments Show -2 older commentsHide -2 older comments
Show -2 older commentsHide -2 older comments
Sign in to comment.
Sign in to answer this question.
See Also
Categories
MATLABData Import and AnalysisData Import and ExportStandard File FormatsImage Data
Find more on Image Data in Help Center and File Exchange
Tags
- data import
- plotting
- image analysis
Products
- MATLAB
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- Deutsch
- English
- Français
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)
Contact your local office