Blunt the Images

15

2

Introduction

Sharp edges are, frankly, just plain dangerous so, given a PNG as input, blur the image using the method described below and blunt those damned sharp edges.

Method

To get the RGB value of each pixel, use the following three equations:

$$R = \sqrt{\frac{1.5\times\sum^n_{a=1}R^2_a}{n}}$$ $$G = \sqrt{\frac{1.5\times\sum^n_{a=1}G^2_a}{n}}$$ $$B = \sqrt{\frac{1.5\times\sum^n_{a=1}B^2_a}{n}}$$

Where \$\sum^n_{a=1}R^2_a\$ is the sum of the red values of each of the adjacent pixels squared. The value of \$n\$ is the number of adjacent pixels (e.g., a corner pixel will have an \$n\$ value of 3, whilst a pixel around the center of the image will have an \$n\$ value of 8).

An adjacent pixel is a pixel which is 1 pixel away from the original pixel in all directions (left, right, up, down and on all of the diagonals).

For example, in the following 3 x 1 image:

The blurred RGB value of the middle pixel will be:

$$R = \sqrt{\frac{1.5*(0^2+0^2)}{2}} = 0$$ $$G = \sqrt{\frac{1.5*(0^2+255^2)}{2}} = 220.836 = 221$$ $$B = \sqrt{\frac{1.5*(255^2+0^2)}{2}} = 220.836 = 221$$

where any decimal outputs are rounded to the nearest unit. You should not simply floor the result.

Therefore, the middle pixel will be the colour (0, 221, 221), or:

Resulting in the image:

You should repeat this process for every pixel in the image. (Note that you do this with the original pixels and not the modified pixels. Basically, you shouldn't overwrite the original image, and should keep it completely separate from the new, blurred image).

If you calculate any values to be greater than 255, assume that its value is 255 (I.e., a value of 374 would be set to 255).

The resulting output should be a separate PNG image (you may name this whatever you wish).

Examples

Super Mario

Original:

Blurred:

Checkerboard

Original:

Blurred:

Crisps

Original

Blurred

Not so crisp anymore

American Gothic

Original:

Blurred:

To see the blur on larger images, it's best to run the program again on the blurred image:

Challenge

The shortest code to blur a given PNG image wins.

You can use image processing libraries (such as PIL) but you must not use built-in blurring functions (Mathematica, I'm looking at you).

Note

As @orlp says below:

For the record, (to my knowledge) this is not a standard blurring method. This challenge is not an educational resource.

Beta Decay

Posted 2016-08-14T14:41:12.350

Reputation: 21 478

I am not really happy with that scaling. n should appear in the denominator. – Karl Napf – 2016-08-14T14:53:22.510

I thought of something very different when I saw "Blunt" :P. – Adnan – 2016-08-14T15:15:14.017

3For the record, (to my knowledge) this is not a standard blurring method. This challenge is not an educational resource. – orlp – 2016-08-14T15:47:19.220

If you had a white pixel surrounded by 8 white pixels (all rgb(255,255,255)), the blurred pixel would be rgb(312,312,312). Are we just supposed to clamp values into the range [0,255]? – kamoroso94 – 2016-08-14T16:46:55.663

How did you get rgb(0,221,221) from red surrounded by all reds (rgb(255,0,0))? It looks like your calculation is averaging two numbers instead of eight. That's impossible since all pixels must have 3, 5, or 8 neighbors, unless the image was less than 3×3 px, but your sample image was sufficiently large enough. Are you sure you were using the center pixel? – kamoroso94 – 2016-08-14T16:54:35.423

1@kamoroso94 1: Yes, assume any number greater than 255 is 255. 2: The example image is supposed to represent a 3 x 1 image. – Beta Decay – 2016-08-14T17:54:25.217

If the image is 1×1, there will be no adjacent pixels. Should the blurred image be black or stay the same color? – kamoroso94 – 2016-08-14T18:23:01.060

@kamoroso94 By the reasoning of the question, it should be black – Beta Decay – 2016-08-14T18:23:39.950

@Mego They are just 1 pixel away and include diagonal directions (hence the n value of 8) – Beta Decay – 2016-08-15T09:02:10.917

Will you repost this with a pure 3D array I/O? If not, may I? – Adám – 2018-02-05T17:18:10.903

@Adám Go ahead :) – Beta Decay – 2018-02-05T17:26:26.147

Answers

5

Python, 354 313 bytes

Not the best, but hey...

Using Space for 1st level indentation, Tab for 2nd level, then Tab+Space and Tab+Tab

import Image as I
A=I.open(raw_input())
w,h=A.size
B=I.new('RGB',(w,h))
s=[-1,1,0]
r=range
for x in r(w):
 for y in r(h):
    P=[]
    for d in s:
     for e in s:
        try:P+=[A.load()[x+e,y+d]]
        except:0
    P.pop()
    B.load()[x,y]=tuple(min(int(.5+(1.5*sum([v*v for v in t])/len(P))**.5),255)for t in zip(*P))
B.save("b.jpg")
  • Edit1: replacing math.sqrt() with ()**.5 thanks to beta decay
  • Edit2: using min for clamping (saving a lot!) and 0 for pass thanks to Loovjo
  • Edit3: +=[] for .append() saving 5 bytes
  • Edit4: using the variable s for the stencil

Karl Napf

Posted 2016-08-14T14:41:12.350

Reputation: 4 131

1Surely n**0.5 is shorter than import math;math.sqrt(n)? Is there a reason for the latter? – Beta Decay – 2016-08-14T20:18:35.313

Yes it is, no there is no reason. I just forgot. – Karl Napf – 2016-08-14T20:26:10.687

2v if v<256 else 255 can be shortened to min(v,255) – Loovjo – 2016-08-14T20:48:08.753

You can also replace pass with 0 – Loovjo – 2016-08-14T20:49:57.997

You need to state which image library you're using. If you're using PIL/Pillow (and it looks like you are), the top import statement should read from PIL import Image as I. – Mego – 2016-08-15T09:22:51.540

@JF Python 3 don't support mixing tabs and spaces – TuxCrafting – 2016-08-15T10:36:00.237

@TùxCräftîñg wow! Never would've thought of that! – J F – 2016-08-15T10:38:20.870

@Mego I'm not sure, but I think import Image as I will work without saying from PIL import Image as I – Beta Decay – 2016-08-15T13:01:02.697

1.5 could be changed to .5. – Yytsi – 2016-08-15T13:51:35.107

@βετѧΛєҫαγ Ohhh. I was so used to look at 0.5. My apologies. – Yytsi – 2016-08-15T14:13:29.953

0

MATLAB, 130 bytes

Takes an image as an input and saves the output as b.png.

i=double(input(''));m=ones(3);m(5)=0;k=@(x)imfilter(x,m);imwrite(uint8(round((1.5*k(double(i.^2))./k(i(:,:,1)*0+1)).^.5)),'b.png')

flawr

Posted 2016-08-14T14:41:12.350

Reputation: 40 560