Remove elements from a matrix
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I have two images with rectangular regions at different locations in the images. I have gotten the pixel locations of each region in the images and stored them in separate matrices. What I wish to do is compare the elements in the matrices to each other and remove duplicates from the second matrix. I also want to remove elements in the second matrix that fall within a certain range of the first matrix.
For example:
Region start and end locations of first matrix(image 1) =
3 18
81 96
109 124
165 180
199 209
299 312
Region start and end locations of second matrix(image 2) =
3 18
25 41
71 83
127 144
164 179
337 354
In the above, the [3 18] should be removed from the second matrix. Also, the [164 179] of the second matrix falls within the [165 180] of the first image and should be removed.
The matrices are not of the same dimensions and the values will be different depending on the images. What would be the best way to remove instances like this? If it's not possible to remove them from the matrix, would there be a way to store them in their own matrix? I looked at using setdiff, which causes instances like [3 18] to be left out, but does not address elements within range. Thanks to anyone who can provide some help.
4 commentaires
Guillaume
le 22 Mar 2016
What about runs that overlap? Should they be collapsed into one? For example, should the [81 96] of image 1 and [71 83] of image 2 become [71 96]?
Réponse acceptée
Guillaume
le 22 Mar 2016
Modifié(e) : Guillaume
le 22 Mar 2016
You can use uniquetol (from R2015a and up) to find duplicate rows with tolerance, applied to the concatenation of the two matrices. It just then is a matter of tracking which of the rows identified as duplicate come from the second matrix:
img1runs = [3 18;81 96; 109 124; 165 180; 199 209; 299 312]
img2runs = [3 18; 25 41; 71 83; 127 144; 164 179; 337 354]
tolerance = 1; %allow interval with ends within +/- 1 of each others
[~, origin] = uniquetol([img1runs; img2runs], tolerance, 'ByRows', true, 'DataScale', 1, 'OutputAllIndices', 1);
origin = origin(cellfun(@numel, origin) > 1); %only keep rows of origin that contain duplicate
origin = vertcat(origin{:}); %concatenate into one row
origin = origin - size(img1runs, 1); %subtract index offset from 1st image. Only indices > 0 come from the second image
img2runs(origin(origin > 0), :) = [] %remove duplicate rows in second image
3 commentaires
Guillaume
le 22 Mar 2016
Before the last line, add:
removedrows = img2runs(origin(origin > 0), :)
Plus de réponses (1)
Image Analyst
le 22 Mar 2016
Why not simply leave them as binary images and deal with them that way? First expand the canvass so that they are the same size. You could use imdilate() to include pixels with a certain "tolerance" (as you say). Then you could use xor() to remove pixels in common. It seems a lot simpler than having to deal with individual coordinates or ranges of where those pixels lie.
3 commentaires
Image Analyst
le 22 Mar 2016
Like if one image is 300x400 and the other is 280x450, make both images 300x450 so they are the same size. You can simply find the largest rows and columns and set the last pixel to be false to expand each image
[rows1, columns1] = size(binaryImage1);
[rows2, columns2] = size(binaryImage2);
% Find the largest of any image in each direction.
bigRows = max([rows1, rows2]);
bigColumns = max([columns1, columns2]);
% Enlarge images by growing to the right and down.
binaryImage1(bigRows, bigColumns) = false;
binaryImage2(bigRows, bigColumns) = false;
Voir également
Catégories
En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!