hazen icon indicating copy to clipboard operation
hazen copied to clipboard

Centroid may be slightly off with some Siemen's data

Open luissantosHCIT opened this issue 1 year ago • 4 comments

Disclaimer If it has not been said before, excellent work! The architecture also matches the Unix philosophy and it is how I approach most of my own software. I think it is really good and you should be proud!

Describe the bug Running hazen acr_geometric_accuracy <siemens_dataset> yields results with off-centered arrows. The scanner is a Siemens 1.5T Magnetom Sola Fit. The acquisition matrix is 0\256\192\0. We have two phantoms and the one used here has the plate for slice 5 instead of the grid. See screenshots below! Per our internal QA, the phantom's positioning should not be the main source of error here. It seems the centroid accuracy is key for several of the ACR tasks which can add small errors to their results.

To Reproduce Run utility against Siemens phantom data using an equivalent phantom to the one shown below.

Expected behavior I expected to see arrows go through most of the holes on the plate.

Screenshots Siemens result image

After small adjustment to HoughCircles() call to use the HOUGH_GRADIENT_ALT as described in here. image

Desktop (please complete the following information):

  • OS: GNU/Linux [Ubuntu]
  • Python version [3.10]
  • Hazen version [1.3.2]
  • Deployment [terminal]

Tentative Solution I did some digging into the documentation and found that the HoughCircles() function has an alternative mode of detection controlled by the HOUGH_GRADIENT_ALT flag. I did a brief control test with the other phantom which was scanned with a Philips scan and changing the flag did not appear to have an adverse effect on that other data. However, it vastly improved the accuracy of the centroid for the phantom data shown in this ticket. Since I am new to the project how would you like me to contribute my change? Would you like me to open a PR against a feature branch? How do you normally run your tests? I will be happy to prepare a PR and do some more testing for you.

I am going to try and find details as to what the alternative detection method is and how it differs from the default detection algorithm.

In the meantime, let me know how I can make my first contribution to the project. Thank you!

luissantosHCIT avatar Oct 15 '24 17:10 luissantosHCIT

Per https://docs.opencv.org/4.x/dd/d1a/group__imgproc__feature.html#gga073687a5b96ac7a3ab5802eb5510fe65aad57c72131c801de427f1fdb55c8c8ad

image

luissantosHCIT avatar Oct 15 '24 17:10 luissantosHCIT

I have a cleaned up version of my changes here staged in my dev fork branch. They include a few added tests. I am in the process of getting clearance to share some of our phantom data as well and will be adding it to the feature branch if I receive the go ahead.

Per the guidelines in this project I need to open a branch here and apply the patchset.

#Questions @mollybuckley

  • What is the conflict with opening and merging PRs from forked feature branches directly?
  • Do you think that opening a feature branch here, merging a PR from the fork to this feature branch, and then opening a PR to main will work?

As an aside, before I attempt a PR, I noticed that the centroid detection gets called more than 2 times when running the acr_geometric_accuracy task. However, only slices 1 and 5 are relevant for this task. I am currently reviewing this. image

luissantosHCIT avatar Jan 15 '25 18:01 luissantosHCIT

Latest cv forced me to change my initial test param2 to 0.9 (recommended in docs) when using the ALT detection method. The results are comparable but slightly a bit off as compared to before updating OpenCV. For documentation purposes, I outline my current findings below.

Parameters

    try:
        detected_circles = cv.HoughCircles(
            img_grad,
            cv.HOUGH_GRADIENT_ALT,
            1,
            param1=300,
            param2=0.9,
            minDist=int(180 / dy),
            minRadius=int(180 / (2 * dy)),
            maxRadius=int(200 / (2 * dx)),
        )
        if detected_circles is None:
            detected_circles = cv.HoughCircles(
                img_grad,
                cv.HOUGH_GRADIENT,
                1,
                param1=50,
                param2=30,
                minDist=int(180 / dy),
                minRadius=int(180 / (2 * dy)),
                maxRadius=int(200 / (2 * dx)),
            )
    except AttributeError as e:
        detected_circles = cv.HoughCircles(
            img_grad,
            cv.HOUGH_GRADIENT_ALT,
            1,
            param1=300,
            param2=0.9,
            minDist=int(180 / dy),
            minRadius=80,
            maxRadius=200,
        )
        if detected_circles is None:
            detected_circles = cv.HoughCircles(
                img_grad,
                cv.HOUGH_GRADIENT,
                1,
                param1=50,
                param2=30,
                minDist=int(180 / dy),
                minRadius=80,
                maxRadius=200,
            )
    return detected_circles.flatten()

Siemens Results

Image

GE Results

Image

Philips Results

Image

Checking all of the tests again to ensure the branch is fully ready for pushing here.

luissantosHCIT avatar Jan 16 '25 17:01 luissantosHCIT

I am ready to submit my code to the project.

luissantosHCIT avatar Jan 16 '25 18:01 luissantosHCIT