Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Radon transformation produces incorrect sinograms (asymmetric, rotational dependency, information loss) #3846

Open
4 tasks done
Dugnom opened this issue Dec 12, 2024 · 1 comment

Comments

@Dugnom
Copy link

Dugnom commented Dec 12, 2024

System information (version)
  • OpenCV => 4.10
Detailed description

The current implementation produces sinograms which do not satisfy basic properties of sinograms.
I will list them and make a few simple examples where the problems can be seen.

I have already prepared a Pull Request, which I will also discuss after describing the problems.

1. Wrong projections due to wrong rotation center

Given a 4x4 matrix with all zeros except one entry at (1,1) we expect the 90 degree rotations to move the entry to (1,2), (2,2), (2,1) and then back to (1,1).

Currently the image is rotated around (2,2), which leads to the following rotations.
grafik
grafik

This also leads to sinograms loosing information in both the cropped and the uncropped case. We can easily see this using a 360 degree rotation, where we expect the values in the upper row to be the same (in a different position) as the lower row. But only the second row from the top has the same values as the lowest row in both the cropped and uncropped version.

I propose to change the center of rotation by (-0.5, -0.5) which leads to the expected rotation in all cases.
grafik

This problem and solution is also discussed in #11784 of the main repo. The solution discussed there is in agreement with this change (no changes in warpAffine, only documentation).

2. Wrong Cropping (Crop = True)

The cropping mask is off-center by half a pixel, even with square source matrix, which leads to changes in the sinogram given the initial rotation of the image:
The circle used to determine the cropping mask is off-center by half a pixel in both axis. This can lead to unexpected differences in sinograms given transposed or flipped images.

I propose to change the center of the "cropping circle" to be offset by (-0.5, -0.5) to be centered. We use the shift parameter of the circle function to achieve this. This improves the cropping, but does not solve it in every case, sometimes the resulting circle is not symmetrical.
grafik

I will create a different issue for the non-symmetrical circle, since it is out of scope for this issue.

3. Wrong Cropping (Crop = True and Crop = False)

Given a matrix with non-integer center (all matrices except squares with odd sidelength) arre currently offset by half a pixel in one or both axis when moved into the square cropping.

Example:
Given a 6x5 matrix wiht (1,1) and (2,2) equal to zero and the rest as ones, we get the follwoing two matrices which will later be rotated:
grafik
In case of Crop = False we are lopsided to the left. Given the tight cropping we will lose information when rotating 45 degrees.
On the other hand, if Crop = True, we will lose only the upper row of information, instead of half of the upper, and half of the lower row.

I propose to use a translation, to move the center of the original source image into the center of the square (cropped or not).

In our example, this would look like this:
grafik

Steps to reproduce
```.cpp
   cv::Mat mat = cv::Mat::zeros(4, 4, CV_32F); // + 1 depending on the example
   double RotationStepAngleTest = 90.0;
   double StartAngleTest = 0.0;
   double EndAngleTest = 360.0;

// Set specific entries to 1
   mat.at<float>(1, 1) = 1; // Row 1, Column 2
   mat.at<float>(2, 0) = 1; // Row 2, Column 2
   mat.at<float>(3, 3) = 1;

   cv::Mat MatCropFalse = mat.clone();
   cv::Mat MatCropTrue = mat.clone();

   cv::Mat SinogramCropFalse;
   cv::Mat SinogramCropTrue;

   RadonTransform(MatCropFalse, SinogramCropFalse, RotationStepAngleTest, StartAngleTest, EndAngleTest, false, false);
   RadonTransform(MatCropTrue, SinogramCropTrue, RotationStepAngleTest, StartAngleTest, EndAngleTest, true, false);

```
Issue submission checklist
  • I report the issue, it's not a question
  • I checked the problem with documentation, FAQ, open issues,
    forum.opencv.org, Stack Overflow, etc and have not found any solution
  • I updated to the latest OpenCV version and the issue is still there
  • There is reproducer code and related data files: videos, images, onnx, etc
@Dugnom
Copy link
Author

Dugnom commented Dec 30, 2024

Since I'm using the shift parameter to create the circle with a diameter of 4, the problem is probably related to opencv/opencv#24978

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant