Suppose i have a 400*300 gray scale image.Now I want to scan each line horizontally and make the average of that line 128,such that the values get scaled as per their difference from mean(128) which will not cause any distortion to image.

  • $\begingroup$ Are you aiming for a solution with a specific programming language / library? $\endgroup$
    – TLousky
    Dec 24, 2015 at 13:13
  • $\begingroup$ solution can be in any language .... what is more important is algorithm $\endgroup$ Dec 24, 2015 at 13:23

1 Answer 1


Here's an example on how to do this with Python, Numpy and Matplotlib. Image on the right has been averaged (row by row), while the left is the original.


EDITED: As suggested by @Nathan Reed, I avoided flipping colors when row average is 0. Rows with an average of 0 now get a value of 0.5 (128). The dark image encountered previously was due to values higher than 1 (255) due to scaling, that were represented as white in matplotlib's image renderer. I fixed this by setting the max value in any pixel to be 1.

import numpy as np
from matplotlib import image as mpimg
from matplotlib import pyplot as plt

def rgb2gray(rgb):
    return np.dot( rgb[...,:3], [0.299, 0.587, 0.144] )

imgPath = "C:/myImg.jpg"

im = mpimg.imread( imgPath )
gs = rgb2gray( im )

averaged = gs.copy()

for row in averaged:
    rowAvg = sum( row ) / len( row )
    if rowAvg == 0:
        row = 0.5
        # Scale each row by ratio between 128 and current row avg
        row *= 0.5 / rowAvg

    # Make sure that no pixel has a higher value than 1
    if rowAvg > 0: row[row>1] = 1

plt.subplot( 1, 2, 1 ), plt.imshow( gs,       'gray' )
plt.subplot( 1, 2, 2 ), plt.imshow( averaged, 'gray' )


Here's another test with a simple gradient image (left is the original): Before-After2

  • 2
    $\begingroup$ Something looks wrong with your first image pair...the result is mostly complete black, which doesn't seem correct. Also, it would be good to handle divide-by-zero so rows that are complete black in the input don't flip out. Maybe just replace the row by all 128s in that case? $\endgroup$ Dec 24, 2015 at 21:30
  • $\begingroup$ Same algorithm for 1st and 2nd img. Will check though, makes sense about the flipping, thanks. $\endgroup$
    – TLousky
    Dec 24, 2015 at 22:20
  • $\begingroup$ The above solution seems correct at first glance but what if user enter the output image as input then it shows distorted output. The solution should be adaptive and learn when not to perform calculation as the output of first input is the solution so when output is again input no changes should be seen. $\endgroup$
    – Sandiip
    Jan 1, 2016 at 7:45
  • $\begingroup$ @SandeepNeupane that makes sense, although that's not what the author of the question asked. I'm sure this answer can serve as the basis for a more adaptive, complete solution. $\endgroup$
    – TLousky
    Jan 1, 2016 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.