What is the best way to detect if an image is pixelated?

Viewed 1090

I am trying to tell whether an image is pixelated or not. I was trying to use the laplacian variance method to do this, but I'm not sure that it is working correctly because a pretty distorted/pixelated image comes back with a very high variance of 1011 using my code:

import sys
import cv2
import imutils as im

csv_filename = sys.argv[1]

def variance_of_laplacian(image):
    # compute the Laplacian of the image and then return the focus
    # measure, which is simply the variance of the Laplacian
    # image = cv2.copyMakeBorder(image, 100, 100, 100, 100, cv2.BORDER_CONSTANT, value = [255, 255, 255])
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # invert gray image
    gray = 255 - gray
    # cv2.imshow("result", gray)
    # cv2.waitKey(0)
    laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
    return laplacian_var

image = im.url_to_image(sys.argv[1])
laplacian_var = variance_of_laplacian(image)
print laplacian_var

Is there another method to detect pixelation in an image or something like that?

Here is one image that I would deem pixelated/distorted/blurry for my tests: test image

3 Answers

I think your issue has to do with ".var()". I do not know what that is. But here is one way to do what you want using numpy.var().

But note, that the variance of the laplacian is not a good way to test for pixelation unless you know you have the same image.

Original Input:

enter image description here

Pixelated Input:

enter image description here

import cv2
import numpy as np

# read original and pixelated image
img1 = cv2.imread('mandril3.jpg')
img2 = cv2.imread('mandril3_pixelated.png')

# convert to grayscale
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

# compute laplacians
laplacian1 = cv2.Laplacian(gray1,cv2.CV_64F)
laplacian2 = cv2.Laplacian(gray2,cv2.CV_64F)

# get variances
variance1 = np.var(laplacian1)
variance2 = np.var(laplacian2)
print ('variance of original image:', variance1)
print ('variance of pixelated image:', variance2)

# save images
cv2.imwrite('mandril3_laplacian.png', (255*laplacian1).clip(0,255).astype(np.uint8))
cv2.imwrite('mandril3_pixelated_laplacian.png', (255*laplacian2).clip(0,255).astype(np.uint8))

# show laplacian using OpenCV
cv2.imshow("laplacian1", laplacian1)
cv2.imshow("laplacian2", laplacian2)
cv2.waitKey(0)
cv2.destroyAllWindows()


Laplacian of original image:

enter image description here

Laplacian of pixelated image:

enter image description here

Variance Results:

variance of original image: 4014.7300553284585
variance of pixelated image: 779.2810668945312


Here is one way to tell if an image is pixelated. Decimate it at two different offsets for the same skip factor and compute the mean of the absolute difference. If the mean is zero, it is pixelated.

In the following, I use a skip of 2 and and offset of 0 and 1.

Original image:

enter image description here

Pixelated image:

enter image description here

import cv2
import numpy as np

# read original and pixelated image
img1 = cv2.imread('mandril3.jpg')
img2 = cv2.imread('mandril3_pixelated.png')

# decimate images by some skip factor (2) for two different offsets (0 and 1)
dec1A = img1[::2, ::2]
dec1B = img1[1::2, 1::2]
dec2A = img2[::2, ::2]
dec2B = img2[1::2, 1::2]

# get mean of absolute difference
diff1 = cv2.absdiff(dec1A, dec1B)
mean1 = np.mean(diff1)
diff2 = cv2.absdiff(dec2A, dec2B)
mean2 = np.mean(diff2)
print('mean absdiff original image:', mean1)
print('mean absdiff pixelated image:', mean2)

# convert to grayscale
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)


Mean results:

mean absdiff original image: 20.53973388671875
mean absdiff pixelated image: 0.0


If we will apply FFT on your image, we will see lins, not very obvious but visible:

Fourier transform

Marked here:

Detect lines

You can compute histograms along X and Y axis, and find if there are pikes. If pikes are higher than defined threshold, you have pixelated image.

You can do fast experimaens using application: http://www.jcrystal.com/products/ftlse/index.htm

Related