0

I am trying to create a color wheel pattern image of given width and height. Something like this:-

enter image description here

How can it be done in a creative pythonic way preferably using opencv and numpy? I found some resources (e.g. here) where inbuilt functions of matloblib are being used.

KaranKakwani
  • 160
  • 12
  • 2
    Your question needs to be more specific IMO. What have you tried to do this so far? Did you try adapting the code that you yourself has linked? Please try and if you run into specific problems when trying to do so, update the question with that. – Ananda Jan 07 '21 at 08:56
  • 1
    this seems like a do my HW question. SO is meant to help debug and improve your code rather than coding a question. I suggest revisiting https://stackoverflow.com/help/how-to-ask. Thank you. – Ehsan Jan 07 '21 at 09:40
  • Yes, I agree I should have mentioned all the things I had tried. Nevertheless, answer from Mark Setchell did help in producing the desired output with minimum lines of python code. Thanks for your comments. :) – KaranKakwani Jan 07 '21 at 19:04

2 Answers2

3

Utilising the cues in Mark Setchell's answer, I am able to generate a color wheel based image of given width and height.

Hue:-

hue = np.fromfunction(lambda i, j: (np.arctan2(i-img_height/2, img_width/2-j) + np.pi)*(180/np.pi)/2,
                              (img_height, img_width), dtype=np.float)

enter image description here

Saturation:-

saturation = np.ones((img_height, img_width)) * 255

enter image description here

Value:-

value = np.ones((img_height, img_width)) * 255

enter image description here

Below is a working code of the same:-

def make_color_wheel_image(img_width, img_height):
    """
    Creates a color wheel based image of given width and height
    Args:
        img_width (int):
        img_height (int):

    Returns:
        opencv image (numpy array): color wheel based image
    """
    hue = np.fromfunction(lambda i, j: (np.arctan2(i-img_height/2, img_width/2-j) + np.pi)*(180/np.pi)/2,
                          (img_height, img_width), dtype=np.float)
    saturation = np.ones((img_height, img_width)) * 255
    value = np.ones((img_height, img_width)) * 255
    hsl = np.dstack((hue, saturation, value))
    color_map = cv2.cvtColor(np.array(hsl, dtype=np.uint8), cv2.COLOR_HSV2BGR)
    return color_map

Resultant Image: enter image description here

KaranKakwani
  • 160
  • 12
2

First you need to think what values you will need in HSV colourspace, and generate those three single-channel layers:

Hue:

enter image description here

Be very careful with the Hue in OpenCV. If your Numpy dtype is np.float, use a range of 0..360. If your Numpy dtype is np.uint8, use a range of 0..180.

Saturation:

enter image description here

Value:

enter image description here

Then combine them using:

HSL = np.dstack((Hue, Saturation, Value))

And convert the result from HSV to BGR colourspace:

wheel = cv2.cvtColor(... cv2.COLOR_HSV2BGR)

enter image description here

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Thanks for your answer. Can you provide some more details on how did you generate the 1st image under HUE? – KaranKakwani Jan 07 '21 at 15:18
  • I've got to leave you a little bit to do! The value of each pixel is determined solely by the angle it makes with the 3 o'clock position - which you can get with `arctan2()`... so, use `np.linspace()`, then `np.meshgrid()` then `np.arctan2()`. Or use `np.fromfunction()`. – Mark Setchell Jan 07 '21 at 15:46
  • Thanks for point me to the correct direction. Utilising your answer, I am able to get the desired output. I'll also post the code as an answer so that others may also get benefited. – KaranKakwani Jan 07 '21 at 18:43