2

I have cropped few images which have gray back ground and need to convert them to white back ground to compare with Reference images.

The following code I implemented to convert:

import cv2
im_gray = cv2.imread('gray_bg.png', cv2.IMREAD_GRAYSCALE)
(thresh, im_bw) = cv2.threshold(im_gray, 255, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imwrite('white_bg.png', im_bw)

input: gray_bg.png

output: white_bg.png

expected output: ex_white_bg

If you observe, my output image has some noise in edges of the original image (I hope I am not wrong in saying). Because of this, while comparing my output with Reference images, I am not getting the desired output. Can someone suggest me how to do it?

Here is the program We wrote to compare two images:

SourceImagePath = r'white_bg.png'
TemplateImagePath = r'ex_white_bg.png'
#def IconValidation(self,SourceImagePath,TemplateImagePath):
sourceImg=cv.imread(SourceImagePath)
templateImg=cv.imread(TemplateImagePath)
_,tempwidth,tempheight=templateImg.shape[::-1]
srcheight = np.size(sourceImg, 0)
srcwidth = np.size(sourceImg, 1)
if(srcwidth < tempwidth) and (srcheight < tempheight):
    print("comparison")

resultImg = cv.matchTemplate(sourceImg,templateImg,cv.TM_CCOEFF_NORMED)
matchVal = resultImg[0][0]
threshold=0.95
if(matchVal>threshold):
    print("passed")

else:
    print("failed")
RSK Rao
  • 193
  • 2
  • 14
  • It would be useful knowing how do you compare the output with the expected one; considering that is the operation that raises issue. – Giova Aug 20 '19 at 07:39
  • updated the code. please have a look – RSK Rao Aug 20 '19 at 09:16
  • After the update to your question, to better answer your needs it would be useful if you also share the model image and how you have obtained it, so other can tests whether the comparison fails or not. For comparison I've used the difference of the sum of the pixels of the images in percentage. – Giova Aug 20 '19 at 13:28

2 Answers2

2

What you see is aliasing, not noise. It appears because of hard thresholding.

You input image does have a little noise, which you see by enlarging (possibly due to lossy compression at some stage), but it is not aliased.

enter image description here

You can turn the gray background to white while keeping the black by applying a gain of 1.4 (the gray level is around 180). This will avoid the introduction of aliasing.

enter image description here

1

Avoiding the change of color encoding achive the best results. Here is the code:

im_gray = cv2.imread('gray_bg.png', cv2.IMREAD_UNCHANGED)
b, g, r = cv2.split(im_gray)

t = [None] * 3
u = [None] * 3
for i, im in enumerate([b, g, r]):
    t[i], u[i] = cv2.threshold(im, 255, 255, cv2.THRESH_BINARY + cv2.THRESH_TRIANGLE)

dst = cv2.merge((*u,))
cv2.imwrite('white_bg.png', dst)

By comparing it with the original it gives 99.99% equality.

Than if you really need it you can convert the image to grayscale encoding with cv2.cvtColor(src, cv2.COLOR_BGR2GRAY).

Result vs Wanted:

Obtained image Wanted image

Giova
  • 1,879
  • 1
  • 19
  • 27
  • This doesn't solve the problem at all, which is caused by binarization. –  Aug 26 '19 at 08:11
  • Dear @YvesDaoust thank you for your consideration. If you have read well the question you'll see "Because of this, while comparing my output with Reference images, I am not getting the desired output." The code sample I've given, among all the test that I've done is the one that gives the best equality comparison results. I've not dealt with the problem of noise like you did, but at least I've given some working code. – Giova Aug 26 '19 at 18:03
  • You don't get it. You did not avoid aliasing, and your output is the same as what the OP obtained. Enlarge the images *without interpolation* to see. –  Aug 26 '19 at 18:54