elerac/polanalyser

Doubts and help to replicate wiki methods

Closed this issue · 6 comments

Hi, I'm currently studying some of the proposed methods found in your code,
however, I find some difficult to replicate some of your stated tests.

Here is the implemented code:

`import cv2
import polanalyser as pa
import matplotlib.pyplot as plt
import NumPy as np

def normarize(image, dtype=np.uint8, gamma=2.2):
"""
Thie function processes image for exporting.
1. apply gamma
2. clip
3. convert dtype
"""
max_val = np.iinfo(dtype).max if (dtype==np.uint8 or dtype==np.uint16) else np.finfo(dtype).max
img_gamma_applied = ((image/max_val)**(1.0/gamma))*max_val
img_normarized = np.clip(img_gamma_applied, 0, max_val).astype(dtype)
return img_normarized

img_raw = cv2.imread('.../dataset/spoons.png',0)
img_demosaiced = pa.demosaicing(img_raw)

fig=plt.figure(figsize=(8, 8))
for i in range(0,4):
fig.add_subplot(1, 4, i+1)
plt.imshow(img_demosaiced[:,:,i],cmap='gray')
plt.title('Img_'+str(i))
plt.axis('off')
plt.show()

radians = np.array([0, np.pi/4, np.pi/2, np.pi*3/4])
img_stokes = pa.calcStokes(img_demosaiced, radians)

img_S0, img_S1, img_S2 = cv2.split(img_stokes)

img_intensity = pa.cvtStokesToIntensity(img_stokes)
img_DoLP = pa.cvtStokesToDoLP(img_stokes)
img_AoLP = pa.cvtStokesToAoLP(img_stokes)
img_Imax = pa.cvtStokesToImax(img_stokes)
img_Imin = pa.cvtStokesToImin(img_stokes)

dtype_raw = img_raw.dtype

plt.subplot(331)
plt.axis('off')
plt.subplot(332)
plt.imshow(normarize(img_intensity, dtype_raw),cmap='gray')
plt.title('Int')
plt.axis('off')
plt.subplot(333)
plt.imshow(normarize(img_DoLP*255, np.uint8,gamma=1),cmap='gray')
plt.title('DoLP')
plt.axis('off')
plt.subplot(334)
plt.imshow(pa.applyColorToAoLP(img_AoLP))
plt.title('AoLP')
plt.axis('off')
plt.subplot(335)
plt.imshow(pa.applyColorToAoLP(img_AoLP, saturation=img_DoLP))
plt.title('AoLP(Hue) + DoLP(Saturation)')
plt.axis('off')
plt.subplot(336)
plt.imshow(pa.applyColorToAoLP(img_AoLP, value=img_DoLP))
plt.title('AoLP(Hue) + DoLP(Value)')
plt.axis('off')
plt.subplot(337)
plt.imshow(normarize(img_Imin, dtype_raw),cmap='gray')
plt.title('Imin')
plt.axis('off')
plt.subplot(338)
plt.imshow(normarize(img_Imax, dtype_raw),cmap='gray')
plt.title('Imax')
plt.axis('off')
plt.subplot(339)
plt.imshow(normarize((img_Imax-img_Imin), dtype_raw),cmap='gray')
plt.title('Specular')
plt.axis('off')
plt.suptitle(str((np.sum(img_DoLP)/(img_DoLP.shape[0]*img_DoLP.shape[1]))))
plt.show()`

Some of the problems I'm facing are obtaining the specular and diffuse reflections as you can see in line 81, I attempt to obtain it however,

I suppose this is wrong. If you see the attached picture is the result of the image of the spoon located on your dataset. As you can see the generated image of the AoLP has a different colourmap than the test located in the wiki, any suggestion about the issue?

Moreover, in line 84, you can see a little estimation of a coefficient of the DoLP, I'm assumpting that the \frac{\sum{DoLP_{values}}}{\#pixels} based on:

Degree of Linear Polarization (DoLP) represents how much the light is polarized. The value is 1 for perfectly polarized light and 0 for unpolarized light. The angle of Linear Polarization (AoLP) represents the polarization angle of the incident light relative to the camera sensor axis. The value ranges from 0 to 180 degrees.

since I'm currently working on an image taken from a polarized or not polarized light those images are compressed, so the question is the DoLP and AoLP are affected by compression such as JPEG?

Also, I'm assuming that the values of the AoLP of the statement are pixel-wise, I'm right?

Finally, let me thank you for share this work and hoping to hear from you...

Figure_1

Hi @londere !
Thanks for bringing up a good point.

I suppose this is wrong. If you see the attached picture is the result of the image of the spoon located on your dataset. As you can see the generated image of the AoLP has a different colourmap than the test located in the wiki, any suggestion about the issue?

As you said, the color of AoLP image is different. This is my mistake. I changed the definition of polarizer angle (see commit log f7ebd05) after I put AoLP images on wiki. However, I haven't changed it to new images yet.
Here's AoLP image generated by the latest code.
spoons_AoLP
Still, you will notice that the color is different. This is because I'm using opencv to display image, not matplotlib. In order to use matplotlib, you need to convert color. Then you will get the same color of AoLP image (mostly light blue).

I'm going to change AoLP image in wiki to a new one.

since I'm currently working on an image taken from a polarized or not polarized light those images are compressed, so the question is the DoLP and AoLP are affected by compression such as JPEG?

Compression may slightly affect the DoLP and AoLP values, but the values are not likely to be significantly different.

Also, I'm assuming that the values of the AoLP of the statement are pixel-wise, I'm right?

Yes!

I am very grateful for your help in finding the mistake. Any other questions?

@elerac, thanks for your quick reply, I corrected the last image with your advice, now I think I had the correct response, please see the attached images.
Also, I find that the gamma correction launch a Warning:

/.../polat.py:14: RuntimeWarning: invalid value encountered in power
img_gamma_applied = ((image/max_val)**(1.0/gamma))*max_val

Since I'm using the scikit-image gamma function I suggest rewriting the used function.

Any other questions?

A lot really, since this is not my area of expertise there are some doubts about the polarization methods. Let me list some of it, also if you could provide a good source to begin will be great!!

  • So the AoLP and DoLP are pixel-wise if you build a coefficient of AoLP or DoLP should be stated as
    CodeCogsEqn
    or in other words np.sum(img_DoLP)/img_DoLP.size if the obtained value is near 0 means the light is unpolarized and nearby 1 is polarized (if you are doing research you could add this approximation) in the case of DoLP and ((np.sum(img_AoLP)/img_AoLP.size)*(180/(np.pi))) to obtain the AoLP of all image, the idea is obtain the type of polarization and angle.

For this, I post some images from the dataset to obtain the polarization angle and degree.

To obtain the specular and diffuse reflections I attempt to do the following (img_Imax-img_Imin) is this correct?

Thanks for your kind support and help.

Figure_1
Figure_2
Figure_3
Figure_4
Figure_5
Figure_6

I corrected the last image with your advice, now I think I had the correct response, please see the attached images.

It looks correct!

I don't know if that's a question you really want to ask, but I'll answer it.

To obtain the specular and diffuse reflections I attempt to do the following (img_Imax-img_Imin) is this correct?

Yes! The specular component is Imax-Imin and the diffuse component is Imin. You can use cvtStokesToSpecular and cvtStokesToDiffuse to get the same result.

if you could provide a good source to begin will be great!!

I am not an expert in all areas of polarization, but here are some good resources for beginners in the field of polarization in computer vision.

Thanks for your response @elerac , I will review the stated literature to begin, I had a final question for you and close the initial issue.

Let's suppose we have an image of an object to be specific a sample from a microscope, this image has been taken from a common digital camera we assume that the taken picture is 90 degrees from the object. But, We want to know first if the light used in that photo is polarized (90 degrees) or not (0 degrees), if it is not polarized we need to recreate or estimate the polarized image. So the question is if we can get the estimated image from the Stokes Matrix or we need to use the Muller Matrix.

In advance, thanks for the provided help.

What you want to do is find out whether the light is polarized or not, right?
As you may know, Imax-Imin (Specular) contains the polarized component, and Imin (Diffuse) contains the unpolarized component. Therefore, in my opinion, it is enough to get the Stokes vector, and the Mueller matrix is not necessary.

Thanks for your kind support, @elerac expecting to contribute if other issues are found, meanwhile this issue and doubts had been solved.

Thanks a lot