As said in other answers, it can be very difficult to quantify "better" and this depends on your problem domain. However, we can quantify "different" (with respect to the original image). This may be able to tell you how much of an effect your changes may have step-by-step.
A common metric for this is the structural similarity index, which is particularly concerned with image texture. Although regular (Shannon's) entropy isn't suitable for images, Larkin (2016) proposes a modification, dubbed "delentropy" for this task. I use an implementation from this gist, which I've condensed make it into a easy to use function:
def delentropy(image):
# Using a 2x2 difference kernel [[-1,+1],[-1,+1]] results in artifacts!
# In tests the deldensity seemed to follow a diagonal because of the
# assymetry introduced by the backward/forward difference
# the central difference correspond to a convolution kernel of
# [[-1,0,1],[-1,0,1],[-1,0,1]] and its transposed, produces a symmetric
# deldensity for random noise.
if True:
# see paper eq. (4)
fx = ( image[:,2:] - image[:,:-2] )[1:-1,:]
fy = ( image[2:,:] - image[:-2,:] )[:,1:-1]
else:
# throw away last row, because it seems to show some artifacts which it shouldn't really
# Cleaning this up does not seem to work
kernelDiffY = np.array( [ [-1,-1],[1,1] ] )
fx = signal.fftconvolve( image, kernelDiffY.T ).astype( image.dtype )[:-1,:-1]
fy = signal.fftconvolve( image, kernelDiffY ).astype( image.dtype )[:-1,:-1]
diffRange = np.max( [ np.abs( fx.min() ), np.abs( fx.max() ), np.abs( fy.min() ), np.abs( fy.max() ) ] )
if diffRange >= 200 and diffRange <= 255 : diffRange = 255
if diffRange >= 60000 and diffRange <= 65535: diffRange = 65535
# see paper eq. (17)
# The bin edges must be integers, that's why the number of bins and range depends on each other
nBins = min( 1024, 2*diffRange+1 )
if image.dtype == float:
nBins = 1024
# Centering the bins is necessary because else all value will lie on
# the bin edges thereby leading to assymetric artifacts
dbin = 0 if image.dtype == float else 0.5
r = diffRange + dbin
delDensity, xedges, yedges = np.histogram2d( fx.flatten(), fy.flatten(), bins = nBins, range = [ [-r,r], [-r,r] ] )
if nBins == 2*diffRange+1:
assert( xedges[1] - xedges[0] == 1.0 )
assert( yedges[1] - yedges[0] == 1.0 )
# Normalization for entropy calculation. np.sum( H ) should be ( imageWidth-1 )*( imageHeight-1 )
# The -1 stems from the lost pixels when calculating the gradients with non-periodic boundary conditions
#assert( np.product( np.array( image.shape ) - 1 ) == np.sum( delDensity ) )
delDensity = delDensity / np.sum( delDensity ) # see paper eq. (17)
delDensity = delDensity.T
# "The entropy is a sum of terms of the form p log(p). When p=0 you instead use the limiting value (as p approaches 0 from above), which is 0."
# The 0.5 factor is discussed in the paper chapter "4.3 Papoulis generalized sampling halves the delentropy"
H = - 0.5 * np.sum( delDensity[ delDensity.nonzero() ] * np.log2( delDensity[ delDensity.nonzero() ] ) ) # see paper eq. (16)
return H
In any case, I'll reiterate that downstream performance metrics are the way to quantify "better," but inspecting the effect of each filter will help guide you on what changes are could be impactful and which may not be.