이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
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];
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!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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 (한국어)