Find 8 extreme pixels to determine skewness

2 vues (au cours des 30 derniers jours)
Bas Dalenoord
Bas Dalenoord le 23 Oct 2015
Modifié(e) : Bas Dalenoord le 27 Oct 2015
Hello,
I'm currently taking a course in Computer Vision and I'm trying to solve a problem, which thus far seems impossible.
I've taken a photo of a map, but the photo is slightly skewed. I want to draw timezones on the map, but they end up in wrong places because of this shear, thus I need to correct the position of timelines for this to work.
The original image has had small blobs removed with 'bwareaopen'. In the image 'Points I want to find' I've circled the exact pixels I want to find in red.
I'm able to draw a bounding box around the entire map using the answer on this page but this leads to the following result: Problematic image.
I want to achieve something like this. This box can be calculated with the X- and Y-positions of the pixels I've circled. If I can find the corners of the box I want immediately, that's fine as well.
Can anyone point me in the right direction to find the exact pixels I've marked?
Regards, Bas

Réponses (1)

Image Analyst
Image Analyst le 23 Oct 2015
Use bwconvhull().
  13 commentaires
Bas Dalenoord
Bas Dalenoord le 27 Oct 2015
Hm. `minboundrect` gives me the bounding rectangle just like I was able to do previously. This does not give me info about the skewness.
`minboundquad` tells me the following:
Index exceeds matrix dimensions
I'm starting with this image, using the following code for bounding rectangle:
[y, x] = find(imgWithoutSmallBlobs);
[rx, ry, area] = minboundrect(x,y);
This gives me just the bounding box
The same call but with 'minboundquad' gives me the following error:
Index exceeds matrix dimensions.
Error in minboundquad (line 133)
k = (edgeangles(edgelist(:,4)) - edgeangles(edgelist(:,1)) <= pi);
'y' and 'x' are both '315271x1 double arrays', minboundquad takes quite a while to run as well, which is quite problematic.
Am I still doing something wrong? I've flipped the output of the find-command, so that shouldnt the problem...
Bas Dalenoord
Bas Dalenoord le 27 Oct 2015
Modifié(e) : Bas Dalenoord le 27 Oct 2015
I've been struggling with this issue for quite some time now, haven't really found a solution with convex hulls thusfar.
I ditched what I had before this afternoon and came up with the following brute-force solution:
  • Call regionprops on the image to calculate circularity and the bounding box per blob
  • Loop over all blobs, removing those that aren't circular enough
  • Take the remaining blobs and their respective bounding boxes. The various corners of these boxes are the corners of my ROI.
This works quite well for specific images where the map is not rotated too much, it might not work for situations where the acquisition of the image was less optimal. I'll try and improve this a bit, for it is an actual solution to my problem.
The code I've written is the following:
% Regionprops
measurements = regionprops(imgWithoutSmallBlobs, 'Area', 'Perimeter', 'PixelIdxList', 'BoundingBox');
% Calculate circularity, only circular blobs will remain
allAreas = [measurements.Area];
allPerims = [measurements.Perimeter];
circularities = allPerims .^ 2 ./ (4*pi*allAreas);
% Remove non-circular blobs
numberOfBlobs = size(circularities,2);
removed = [];
for blobIdx = 1:numberOfBlobs
circularity = circularities(blobIdx);
measurement = measurements(blobIdx);
if((circularity > 2) == 1)
imgWithoutSmallBlobs( vertcat( measurement.PixelIdxList ) ) = 0;
removed = vertcat(removed,blobIdx);
end
end
measurements(removed) = [];
numberOfBlobs = size(measurements,1);
if numberOfBlobs ~= 4
numberOfBlobs
error('Invalid number of blobs');
end
% Calculate the corners of the overall bounding box
topLeft = measurements(1).BoundingBox;
topLeftX = topLeft(1);
topLeftY = topLeft(2);
topRight = measurements(3).BoundingBox;
topRightX = topRight(1) + topRight(3);
topRightY = topRight(2);
bottomRight = measurements(4).BoundingBox;
bottomRightX = bottomRight(1) + bottomRight(3);
bottomRightY = bottomRight(2) + bottomRight(4);
bottomLeft = measurements(2).BoundingBox;
bottomLeftX = bottomLeft(1);
bottomLeftY = bottomLeft(2) + bottomLeft(4);
Dirty, but at least usable for this specific image... I'll try and improve it for different images later

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by