Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to determine "visual clarity", or pixelation of an image

Is there any such way to determine how much an image could be enlarged until it is considered "out of focus"?

A practical example (and the problem I'm trying to solve):

I have an image saved at several different sizes, say 500x500, 250x250, and 120x120. I want to serve the most efficient image, but also the most clear. If a user was to request an image at 125x125, obviously increasing the 120x120 image to accommodate would not only be most efficient but most likely would not cause any apparent pixelation.

Yet, if a user was to request an image at 180x180, it may be more efficient to increase the 120x120 image, but most likely would render a blurry image. In this case, I would want to shrink the 250x250 image.

Obviously the "clarity" of an image can be relative and vary from eye to eye, as well as image to image, but I'm wondering if there is any sort of algorithm or function to determine a "pixelation index" of sorts...Thanks!

Note: using PHP & ImageMagick for image manipulations, so any answer in that realm would be great...

For Clarification: I'm not exactly looking for a solution to my above example. I'm looking for an answer to the original question: is there an algorithm that could possibly determine how "pixelated" a blown up image is...The above problem is just a practical example of how such algorithm could be useful.

like image 650
anson Avatar asked May 30 '13 19:05

anson


1 Answers

You could do a grey-scale sobel edge detection filter on the image, and sum up the pixel values of the edges;then average this summation against the number of pixels ( SumOfEdges/(width*height)). That would tell you the "edginess" of the image. This could only be used to compare images type.

This is my sobel opencl filter kernel

const sampler_t sampler = CLK_ADDRESS_CLAMP_TO_EDGE |
CLK_FILTER_NEAREST;
kernel void
sobel_grayscale(read_only image2d_t src, write_only image2d_t dst)
{
int x = get_global_id(0);
int y = get_global_id(1);

float4 p00 = read_imagef(src, sampler, (int2)(x - 1, y - 1));
float4 p10 = read_imagef(src, sampler, (int2)(x, y - 1));
float4 p20 = read_imagef(src, sampler, (int2)(x + 1, y - 1));
float4 p01 = read_imagef(src, sampler, (int2)(x - 1, y));
float4 p21 = read_imagef(src, sampler, (int2)(x + 1, y));
float4 p02 = read_imagef(src, sampler, (int2)(x - 1, y + 1));
float4 p12 = read_imagef(src, sampler, (int2)(x, y + 1));
float4 p22 = read_imagef(src, sampler, (int2)(x + 1, y + 1));

float4 gx = -p00 + p20 + 2.0f * (p21 - p01)-p02 + p22;

float4 gy = -p00 - p20 +2.0f * (p12 - p10) +p02 + p22;

float gs_x = 0.3333f * (gx.x + gx.y + gx.z);
float gs_y = 0.3333f * (gy.x + gy.y + gy.z);
float g = native_sqrt(gs_x * gs_x + gs_y * gs_y);
write_imagef(dst, (int2)(x, y), (float4)(g,g,g, 1.0f));
}
like image 80
Mercutio Calviary Avatar answered Sep 18 '22 07:09

Mercutio Calviary