現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
Segment extraction from an image in any direction
1 回表示 (過去 30 日間)
古いコメントを表示
Alejandro
2014 年 7 月 4 日
Hi, i'm trying to extract a segment from an image in any direction. Suppose i have an 800X600 image (RGB) and i want to read a segment from point A(500,200) to point B(300,600). Is there any way i can get a column vector which contains the pixels values in that "diagonal"? i think it has to be some sort of interpolation between the nearest pixels. I don´t want to rotate the image, i need the values as they are. Regards.
採用された回答
Image Analyst
2014 年 7 月 4 日
Yes. You can use improfile()
x = [200, 600];
y = [500, 300];
values = improfile(grayImage, x, y);
33 件のコメント
Alejandro
2014 年 7 月 4 日
That seems to work, thanks!!!! but there is a way to display that array (i have an rgb image) as an image? right now i'm getting a black line. I need to apply this to a number of images and create a matrix which contains all the vectors from those images, and display the "new" image with all the previous segments. Sorry for "segmentation"
Image Analyst
2014 年 7 月 4 日
It's just a line so you can plot it with plot(). If you really want an image of an all black rectangle except for one gray level line, then you'll have to use imline and create a mask that you can multiply by your image. See attached demo.
Alejandro
2014 年 7 月 4 日
I'm going to check that. What i need to do is displayed in the attached image.
Image Analyst
2014 年 7 月 4 日
Just do
x = [200, 600];
y = [500, 300];
values = improfile(grayImage, x, y);
bar(values);
Alejandro
2014 年 7 月 4 日
sorry for not explaining myself well. The attached image is an image created with 1920 vectors concatenated into a matrix. Each vector belongs to a certain image. It is done by selecting two points from an image (two points in the same horizontal coordinate) and reading the pixels between those points. As the two points were in the same horizontal coordinate, i had no problems. But now i have to do it in any direction (from A to B as i explained before). I thought improfile would solve the problem, but as i explained to you before, when i use imshow() on the generated vector "values" it displays a black image. I need it to be a "color" segment or image. Hope it make sense now.
Alejandro
2014 年 7 月 4 日
i couldn't do it with the explame you send me. I was trying to use Bresenham's line algorithm, but that only gave me the coordinates, i need the values aswell and the plot.
Image Analyst
2014 年 7 月 4 日
You can do it with improfile. It interpolates a straight line which is better than the jagged one you get from Bresenham. You just need to pass in a constant number of samples to improfile and then tack them on to an array:
x = [200, 600];
y = [500, 300];
values = improfile(grayImage, x, y, 300);
% Stitch this profile on to the rest of them.
theImage = [theImage, values];
You might have to transpose values if it's a row vector instead of a column vector.
Alejandro
2014 年 7 月 4 日
編集済み: Alejandro
2014 年 7 月 4 日
i get this error: Error using horzcat Dimensions of matrices being concatenated are not consistent. Error in pruebayborra (line 9) A=[A,values];
values is a column vector 1301x1x3 double and A is my RGB image 1080x1920x3 uint8
I think i have to initialize a matrix of the size of values.
Image Analyst
2014 年 7 月 4 日
It's more complicated for a color image. You might have to do it on each color channel one at a time.
Alejandro
2014 年 7 月 4 日
i keep getting the same error, even when i do it on each color.
what is this:
theImage = [theImage, values];
in my code grayImage,theImage = A (RGB)
Image Analyst
2014 年 7 月 4 日
If you extracted each color channel into it's own grayscale image, then why does improfile give you a 1301x1x3 array? It won't. It will give you a 1D array. You'll have to share more of your code.
Alejandro
2014 年 7 月 4 日
sorry, that was before i did it with each color.
A=imread('img_calib.png');
x = [100, 1400];
y = [700, 200];
values=improfile(A(:,:,1),x,y,'bicubic');
A=[A,values];
Error using horzcat
Dimensions of matrices being concatenated are not consistent.
Error in pruebayborra (line 9)
A=[A,values];
Alejandro
2014 年 7 月 4 日
編集済み: Alejandro
2014 年 7 月 4 日
i tried with a random vector:
b=zeros(1080,300);
A=[A(:,:,1),b];
imshow(A);
and this displays the image with a black rectangle on the side. It is not quite i have to do but still, i need to display as an image the "values" vector. Any way i can do that?
Image Analyst
2014 年 7 月 4 日
Well you need to put some thought into this. You're taking a profile from two points somewhere in the image, right? Now the number of samples taken along that line would not necessarily be the same as the number of rows in the image, would it? Of course not, so you don't want to append the line to the entire original RGB image (the poorly-named "A") like you tried to do. That makes no sense.
You said you need to do lots of these lines: "I need to apply this to a number of images and create a matrix which contains all the vectors from those images" So how can we do that? Well how about we loop over all the images and in the loop we have a call to improfile. On the first image, there is nothing to append to so the first one we just take the profile itself to get started. Only if the loop index if >=2 do we append. So don't you think you'll need to do something like this inside your loop
rgbImage = imread(filenames(k).name); % read kth image.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
x = [100, 1400];
y = [700, 200];
redValues=improfile(redChannel,x,y,'bicubic');
if k == 1
redProfiles = redValues;
else
redProfiles = [redProfiles, redValues];
end
Do the same for the green and blue channels. Then make an RGB image from them like
rgbProfiles = cat(3, redProfiles, greenProfiles, blueProfiles);
If you don't know how to loop over the filenames, see the FAQ: http://matlab.wikia.com/wiki/FAQ#How_can_I_process_a_sequence_of_files.3F
Alejandro
2014 年 7 月 4 日
ok, let me check. Actually i have the loop code. I need to display improfile as an image. Let me check.
Alejandro
2014 年 7 月 4 日
i still get a black line.
rgbImage=imread('img_calib.png');
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
x = [100, 1400];
y = [700, 200];
redValues=improfile(redChannel,x,y,'bicubic');
greenValues=improfile(greenChannel,x,y,'bicubic');
blueValues=improfile(blueChannel,x,y,'bicubic');
redProfiles = uint8(redValues);
greenProfiles = uint8(greenValues);
blueProfiles = uint8(blueValues);
%Do the same for the green and blue channels. Then make an RGB image from them like
rgbProfiles = cat(3, redProfiles, greenProfiles, blueProfiles);
imshow(rgbProfiles);
This is for one image. I tried changing to uint8 and still get the black line.
Image Analyst
2014 年 7 月 4 日
That's not what I showed you. Where is the "if k==1" stuff????? Well that's my last post for the day most likely. I'll be out until almost midnight. Good luck.
Alejandro
2014 年 7 月 4 日
i was testing with one image. I can't do it for all the images if the code is not working.
Alejandro
2014 年 7 月 4 日
correction, that seems to work. Let me do it with all the images (2000). i'm trying to initialize a matrix because "redProfiles" is changing size in every loop.
Alejandro
2014 年 7 月 4 日
編集済み: Alejandro
2014 年 7 月 4 日
ok, i did it, but i couldn't initialize an array and display it as the final image. I'm trying to do that because i think the process would be faster. Is that correct?
weel, here's the array %vect_foto = zeros(abs(x(2)-x(1))+1,n2,3); and here is the code.
lee_archivos2 = dir('*.jpg');
dimension2 = length(lee_archivos2);
n2 = dimension2;
B2 = 1:n2; %B2 es un vector fila
for k=1:n2
ttt=sscanf(lee_archivos2(k).name(7:end),'%ld');
B2(k)=ttt;
end
%disp(B2);
[sorted_array2,orden2] = sort(B2);%B = sort(A) sorts the elements along different dimensions of an array,
%and arranges those elements in ascending order. a can be a cell array of strings
x = [100, 1400];
y = [700, 200];
%vect_foto = zeros(abs(x(2)-x(1))+1,n2,3);
wbr = waitbar(0,'1','Name','Espere Por Favor',...
'CreateCancelBtn',...
'setappdata(gcbf,''canceling'',1)');
setappdata(wbr,'canceling',0)
for j = 1:n2 %recorre número de archivos guardados en el directorio
ima_read = imread(lee_archivos2(orden2(j)).name); %se lee cada imagen ascendentemente
redChannel = ima_read(:, :, 1);
greenChannel = ima_read(:, :, 2);
blueChannel = ima_read(:, :, 3);
redValues=improfile(redChannel,x,y,'bicubic');
greenValues=improfile(greenChannel,x,y,'bicubic');
blueValues=improfile(blueChannel,x,y,'bicubic');
if j == 1
redProfiles = uint8(redValues);
greenProfiles = uint8(greenValues);
blueProfiles = uint8(blueValues);
else
redProfiles = [redProfiles, redValues];
greenProfiles = [greenProfiles, greenValues];
blueProfiles = [blueProfiles, blueValues];
end
%Do the same for the green and blue channels. Then make an RGB image from them like
rgbProfiles = cat(3, redProfiles, greenProfiles, blueProfiles);
if getappdata(wbr,'canceling')
break
end
waitbar(j/n2,wbr,{sprintf('%g%%Completado',...
fix(100*(j/(n2))))});
fclose('all');
clear ima_read rotate_ima vect1 ttt B2 sorted_array2
end
delete(wbr);
%size(rgbProfiles)
imshow(rgbProfiles);
Alejandro
2014 年 7 月 4 日
i have another question regarding the pixel coordinate of "redvalue" in the original image. i'll ask when you respond. Regards.
Image Analyst
2014 年 7 月 5 日
You can pass in a size for the profile so that it will be the same length for every profile it extracts. That way you can stitch the current image's profile onto the growing image of all profiles.
Alejandro
2014 年 7 月 5 日
it seems it doesn't affect the computation time when i initialize the vectors. it should, shouldn't it? (this is my final qustion, i already solved the problem of the coordinates)
Image Analyst
2014 年 7 月 5 日
I don't know since you're not showing the code. It may or may not make a noticeable difference in run time.
Alejandro
2014 年 7 月 5 日
lee_archivos2 = dir('*.jpg');
dimension2 = length(lee_archivos2);
n2 = dimension2;
B2 = 1:dimension2; %B2 es un vector fila
for k=1:n2
ttt=sscanf(lee_archivos2(k).name(7:end),'%ld');
B2(k)=ttt;
end
%disp(B2);
[sorted_array2,orden2] = sort(B2);%B = sort(A) sorts the elements along different dimensions of an array,
%and arranges those elements in ascending order. a can be a cell array of strings
x = [100, 1400];
y = [700, 200];
wbr = waitbar(0,'1','Name','Espere Por Favor',...
'CreateCancelBtn',...
'setappdata(gcbf,''canceling'',1)');
setappdata(wbr,'canceling',0)
cx = zeros(abs(x(2)-x(1))+1,n2);
cy = zeros(abs(x(2)-x(1))+1,n2);
cx2 = zeros(abs(x(2)-x(1))+1,n2);
cy2 = zeros(abs(x(2)-x(1))+1,n2);
cx3 = zeros(abs(x(2)-x(1))+1,n2);
cy3 = zeros(abs(x(2)-x(1))+1,n2);
redValues = zeros(abs(x(2)-x(1))+1,n2);
greenValues = zeros(abs(x(2)-x(1))+1,n2);
blueValues = zeros(abs(x(2)-x(1))+1,n2);
for j = 1:n2 %recorre número de archivos guardados en el directorio
ima_read = imread(lee_archivos2(orden2(j)).name); %se lee cada imagen ascendentemente
redChannel = ima_read(:, :, 1);
greenChannel = ima_read(:, :, 2);
blueChannel = ima_read(:, :, 3);
[cx(:,j),cy(:,j),redValues(:,j)]=improfile(redChannel,x,y,'bicubic');
[cx2(:,j),cy2(:,j),greenValues(:,j)]=improfile(greenChannel,x,y,'bicubic');
[cx3(:,j),cy3(:,j),blueValues(:,j)]=improfile(blueChannel,x,y,'bicubic');
%if j == 1
% redProfiles = uint8(redValues);
% greenProfiles = uint8(greenValues);
% blueProfiles = uint8(blueValues);
%else
% redProfiles = [redProfiles, redValues];
% greenProfiles = [greenProfiles, greenValues];
%blueProfiles = [blueProfiles, blueValues];
%end
redProfiles = uint8(redValues);
greenProfiles = uint8(greenValues);
blueProfiles = uint8(blueValues);
%Do the same for the green and blue channels. Then make an RGB image from them like
rgbProfiles = cat(3, redProfiles, greenProfiles, blueProfiles);
if getappdata(wbr,'canceling')
break
end
waitbar(j/n2,wbr,{sprintf('%g%%Completado',...
fix(100*(j/(n2))))});
fclose('all');
clear ima_read rotate_ima vect1 ttt B2 sorted_array2
end
delete(wbr);
imshow(rgbProfiles);
Image Analyst
2014 年 7 月 5 日
You are still not passing in a number to improfile to tell it how many elements to take, though it will probably be the same number every time since x and y are the same every time.
Alejandro
2014 年 7 月 5 日
yes. x and y are the same for every loop. I change the values before the loop just for test the code. How can ia pass in the number to improfile?
Image Analyst
2014 年 7 月 5 日
numberOfSamplesToTake = round(sqrt((x(1)-x(2))^2+(y(1)-(2))^2));
[cx(:,j),cy(:,j),redValues(:,j)] = improfile(redChannel,x,y, ...
numberOfSamplesToTake, 'bicubic');
Alejandro
2014 年 7 月 5 日
oh, ok. That is the distance between the points, but it increases the size of the vector. Is there any advantage regarding the precision of the pixel values in the final image (rgbProfiles)? Because the run time is the same, a little longer i would say.
Image Analyst
2014 年 7 月 5 日
That's using the same spacing as the original sampling. You can go higher for more "resolution" though it's just giving you more samples, not necessarily giving more information, or you can use a smaller number if you want a sampling less frequent than you have in the image. It's your choice. Do whatever you want considering the time to process and what you want to do with the final image you're building up.
その他の回答 (0 件)
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- 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
- United Kingdom (English)
アジア太平洋地域
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)