Interactive pixel extraction from an image along custom line

25 次查看(过去 30 天)
The following code extracts pixel values for the first column of an image.
IMt = imread('test.jpg');
% convert to double format
IMtd=double(IMt);
% isolate first trace
trace=(IMtd(:,1));
What I need to do instead is extract the pixel values along an arbitrary line (see red lines in below image). In other words, along a direction which is diagonal to rows and columns.
Is there a tool in Matlab available where one can plot an image and then interactively draw a line along which the values will be extracted?
If I use...
imshow(IMt)
datacursormode on
...the pixel values are interactively displayed when I hove over the image. There just needs to be a way to write them into an array at the same time.

采纳的回答

Image Analyst
Image Analyst 2020-6-6
Try improfile()
or drawline() with a callback function
  5 个评论
Image Analyst
Image Analyst 2020-6-7
You never know before you draw the line but once you draw it, you know, and that's what I computed and passed in.
You can rate it one star in the help and it will bring up a form that you can put your comment.
Z.S.
Z.S. 2021-7-2
I think the variables linestart and lineend are miss-positioning the x and y coordinates of the end points for using improfile. According to the help page of improfile, the format should be improfile(I,x,y). Then the code should be something like:
I = imread('liftingbody.png');
imshow(I);
roi = drawline('Color','r');
% now draw line interactively
%
% Read out the X and Y coordinates of the start and end points
line_xs = [roi.Position(1,1), roi.Position(2,1)]
line_ys = [roi.Position(1,2), roi.Position(2,2)];
% extract pixel values along line
pixvals = improfile(I,line_xs,line_ys);
figure
plot(pixvals,1:length(pixvals),'k'), axis tight, title('pixel values')
xlabel('pixel greyscale values')
ylabel('relative position from linestart (0) to lineend')

请先登录,再进行评论。

更多回答(1 个)

Julianna Mather
Julianna Mather 2020-6-8
I've been thinking about how to frame the enhancement request for the functionality you requested, and I have some questions.
I'm curious to know what your ultimate goal is and what exactly you want to happen along the diagonals.
Suppose you have a diagonal line that crosses through a pixel just a tiny, tiny bit, should it get counted? Or perhaps it would be appropriate to determine the number of rows and columns the diagnol spans and then use hypot to figure out the number of pixels to sample uniformly along the line. (You can do that right now with improfile now, of course, for non-interactive syntaxes.)
So all of this gets me to the first question: What is your ultimate goal of having improfile return more pixel sites? How will you use that increased resolution?
(BTW, I'm not critiquing your request, I just want to make sure that we get a solution that will satisfy your use case.)
  1 个评论
Florian
Florian 2020-6-8
编辑:Florian 2020-6-8
Hi Jeff,
thanks for getting in touch. Let's go back to my first comment dated 7 Jun 2020 at 7:20. My point here was to try first if improfile reads the pixels along a drawn line as one would expect from the image data.
In the example I showed (see my attached file in the first comment by scrolling all the way to the right), I drew a straight line from the top to the bottom of the liftingbody.png image whose size is 512 x 512 pixels. As you can see from the workspace variables on the left of the attached file, the drawn line start and end point both coincided with column 249 of the image. In this case I would thus expect that improfile returns 512 values which is the length of each column. Instead, improfile only returned 265 values (pixvals variable in the workspace). So this first example tells me that there is a problem reading out the pixel values along a straight line. When you then go to the right of my attached file then Matlab Figure 2 shows the greyscale values which were extracted along the drawn line. The first 100 values or so correspond to the greyish interval on top of the flying object, while the ones after correspond to the object itself (values in the 200s matching the whitish color of the flying object). Please note that there are NO greyscale values which belong to the grey interval below the flying object. So that is the other point which concerns me: the capture of pixel values just stops somewhere along the drawn line and doesn't continue to the end of the image in accordance with the drawn line.
Maybe there is something wrong in my assessment here, but to me it seems the function improfile does not return the right values along the drawn line. So the first thing would just be to verify if my two observations explained above are correct and as a result there needs to be an improvement made to the improfile function.
The second step would then be to look at diagonal lines, and if I say diagonal then I would like improfile to retun a number of pixels which is close to the actual number of pixels, as defined by Image Analyst in this code
numSamples = round(sqrt((linestart(1) - lineend(1)).^2 + (linestart(2) - lineend(2)).^2))
pixvals = improfile(I,linestart,lineend, numSamples);
So using a full diagonal in a 512 x 512 pixel image, this would amount to 724 pixel values. And the pixels which are sampled are equally sampled along the drawn line, not ending 1/2 or 2/3 down the line.
Kind regards,
Florian

请先登录,再进行评论。

Community Treasure Hunt

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

Start Hunting!

Translated by