OpenStitching / stitching

A Python package for fast and robust Image Stitching
Apache License 2.0
1.99k stars 156 forks source link

ConfidenceThreshold 0 does not work together with RangeMatcher #56

Closed Kalo0m closed 1 year ago

Kalo0m commented 1 year ago

Hi,

I would like to use your library in order to make a 360 picture of a room (with a set of 12-13 pictures). I'm using band-width=1 because I know the order, confidence_threshold 0 and Subsetter(0). But when I try to link images, some links are a bit weird because features are only located in one place (as you can see below). Am I missing an option which can ce useful in my usecase? or maybe it's my camera which optimize settings (according to the environment) and create mismatches between images

image

Thanks for your help

lukasalexanderweber commented 1 year ago

Can you show the result?

Kalo0m commented 1 year ago

test1 test2 test3 test4

I have tested with these 4 pictures and I get this result

result

And as you can see, the fourth image is not in the result, do you have any suggestion?

lukasalexanderweber commented 1 year ago

can you give me the matches_graph_dot_file e.g. with --matches_graph_dot_file matches.txt

Kalo0m commented 1 year ago
graph matches_graph{
"test1.jpg" -- "test2.jpg"[label="Nm=64, Ni=31, C=1.13971"];
"test1.jpg" -- "test3.jpg"[label="Nm=0, Ni=0, C=0"];
"test1.jpg" -- "test4.jpg"[label="Nm=0, Ni=0, C=0"];
}

and the order is test1 - 2 - 3 - 4 and here is my command : stitch imgs/test1.jpg imgs/test2.jpg imgs/test3.jpg imgs/test4.jpg --range_width 1 --confidence_threshold 0 --matches_graph_dot_file matches.txt

but as you can see, there are some mismatch in the cabinet and on the radiator. Can we fix these?

lukasalexanderweber commented 1 year ago

thats odd. The matches graph should look like this:

graph matches_graph{ "test1.jpg" -- "test2.jpg"[label="Nm=64, Ni=31, C=1.13971"]; "test2.jpg" -- "test3.jpg"[label="Nm=0, Ni=0, C=0"]; -> not 0 "test3.jpg" -- "test4.jpg"[label="Nm=0, Ni=0, C=0"]; -> not 0 }

maybe there is a bug in range_width

Kalo0m commented 1 year ago

@lukasalexanderweber I've done some research in your code and it looks like thecv.detail.matchesGraphAsString method return always test1.jpg when we pass confidence_threshold=0. I've reproduced an example:

import stitching

settings = {
    "range_width": 1,
    "confidence_threshold": 0.1,
    "matches_graph_dot_file": "matches_graph.dot"
}   
settings2 = {
    "range_width": 1,
    "confidence_threshold": 0,
    "matches_graph_dot_file": "matches_graph2.dot"
}   
stitcher = stitching.Stitcher(**settings)
stitcher2 = stitching.Stitcher(**settings2)

images = ["test1.JPG", "test2.JPG", "test3.JPG", "test4.JPG", "test5.JPG", "test6.JPG", "test7.JPG"]
stitcher.initialize_registration(images)
stitcher2.initialize_registration(images)

imgs = stitcher.resize_medium_resolution()
features = stitcher.find_features(imgs)
matches = stitcher.match_features(features)

imgs2 = stitcher2.resize_medium_resolution()
features2 = stitcher2.find_features(imgs2)
matches2 = stitcher2.match_features(features2)

stitcher.subset(imgs, features, matches) # works
stitcher2.subset(imgs, features, matches) # doesn't work

matches_graph.dot

graph matches_graph{
"test1.JPG" -- "test2.JPG"[label="Nm=62, Ni=31, C=1.16541"];
"test2.JPG" -- "test3.JPG"[label="Nm=66, Ni=31, C=1.11511"];
"test3.JPG" -- "test4.JPG"[label="Nm=54, Ni=39, C=1.61157"];
"test4.JPG" -- "test5.JPG"[label="Nm=30, Ni=17, C=1"];
"test5.JPG" -- "test6.JPG"[label="Nm=85, Ni=56, C=1.67164"];
"test6.JPG" -- "test7.JPG"[label="Nm=107, Ni=80, C=1.99501"];
}

matches_graph2.dot

graph matches_graph{
"test1.JPG" -- "test2.JPG"[label="Nm=64, Ni=31, C=1.13971"];
"test1.JPG" -- "test3.JPG"[label="Nm=0, Ni=0, C=0"];
"test1.JPG" -- "test4.JPG"[label="Nm=0, Ni=0, C=0"];
"test1.JPG" -- "test5.JPG"[label="Nm=0, Ni=0, C=0"];
"test1.JPG" -- "test6.JPG"[label="Nm=0, Ni=0, C=0"];
"test1.JPG" -- "test7.JPG"[label="Nm=0, Ni=0, C=0"];
}

I don't know how to solve this, maybe replace the 0 by a very small value when calling matchesGraphAsString?

lukasalexanderweber commented 1 year ago

Thanks for reproducing! I think it's an opencv internal issue. For know we should be fine throwing an error that confidence must not be 0 if range matcher is used. Do you want to implement it?

Kalo0m commented 1 year ago

Yes I can, I will try to do it this evening. But should I throw when the user wants to use graphAsString, or in the stitching constructor? Because everything seem to work fine except the string representation so would it be better to throw in the asString method?

lukasalexanderweber commented 1 year ago

Good question.


stitcher.subset(imgs, features, matches) # works
stitcher2.subset(imgs, features, matches) # doesn't work

so the stitching result is the same for both approaches?

Then I would like your approach better:

maybe replace the 0 by a very small value when calling matchesGraphAsString

Maybe here just ask if self.confidence_threshold is 0 and if yes, replace it with 0.0001 or so

Kalo0m commented 1 year ago

Yes if I remember well, only the graph representation doesn't work. The result is the same but I will double check this to be sure.

Kalo0m commented 1 year ago

@lukasalexanderweber done! https://github.com/lukasalexanderweber/stitching/pull/59

lukasalexanderweber commented 1 year ago

closed with dbc36e47eb7e963f07cc3297b848fae7f20b699a