1

I am quite new to python, therefore I might risk a duplicate (but I don't know how to ask the web yet).

I have coded the following method. It converts an array(ROWS,COLS,3) to array(ROWS,COLS,1)

def convert_greyscale( rgb ):
    rgb_greyscale = np.zeros( (rgb.shape[0],rgb.shape[1]), dtype=np.uint8)
    for row in range(0, rgb.shape[0]:
        for col in range(0, rgb.shape[1]):
            rgb_greyscale[row][col] = int(0.2126 * rgb[row][col][0] + 0.7152 * rgb[row][col][1] + 0.0722 * rgb[row][col][2])
    return rgb_greyscale

Sadly I wasn't able to reproduce it shorter. There is already a post where someone already mentioned a solution with np.dot, however it is not the same result as my small function.

How can I rewrite this code using more efficient (lambda) or at least more elegant expressions?

And is this method efficient?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
jaecktec
  • 440
  • 4
  • 15
  • Just use proper weights there : `[0.2126, 0.7152, 0.0722]` with the answers to the linked question, specifically this one - https://stackoverflow.com/a/12201744/ – Divakar Jul 24 '17 at 12:43
  • yeah I've found this Solution too, (mentioning np.dot). It doesn't deliver the same results. – jaecktec Jul 24 '17 at 12:58
  • It does. You also need to convert to `int` dtype as you were doing in your code and seems like you are skipping the last row and col, so pad with zeros. – Divakar Jul 24 '17 at 13:00
  • the -1 was incorrect. forgot to delete it. so basicly what differs from this answer is: np.dot(rgb[...,:3], [0.299, 0.587, 0.114]).astype(np.uint8) ? – jaecktec Jul 24 '17 at 13:01
  • Not sure which `-1` you are referring to. This is as simple as : `np.dot(rgb, [0.2126, 0.7152, 0.0722]).astype('uint8')`. – Divakar Jul 24 '17 at 13:04
  • can I expect any performance differences when using `np.dot(img, [0.2126, 0.7152, 0.0722]).astype('uint8')` over `(0.2126*rgb[:,:,0]+0.7152*rgb[:,:,1]+0.0722*rgb[:,:,2]).astype(np.uint8)` – jaecktec Jul 24 '17 at 13:06
  • Well there's a faster way : `np.tensordot(rgb, [0.2126, 0.7152, 0.0722], axes=((-1,-1)))`. – Divakar Jul 24 '17 at 13:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/150000/discussion-between-coco-and-divakar). – jaecktec Jul 24 '17 at 13:15

1 Answers1

2

You can simply use:

return (0.2126*rgb[:,:,0]+0.7152*rgb[:,:,1]+0.0722*rgb[:,:,2])\
           .astype(np.uint8)

No need for loops here, let numpy do the iterations.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555