Vision: How do I Convert a Color Image to Grayscale?

This lesson describes how to convert a color image into grayscale using widely accepted conversion constants. Sample code and example screen captures are provided.

Introduction

Vision is possibly the most important human sense. It allows us to observe and assess the environment around us with a wealth of color, texture and depth information. We can act upon this information in a seemingly effortless fashion, but the processes that underlie human vision and visual perception are in fact far from fully researched or understood.

A lot of computer image processing can and is conducted on gray level pictures as this simplifies the implementation of many algorithms. Gray level images provide a wealth of information but at the same time eliminate the need to handle color channels. Of course there are a number of applications that do utilize color in images.

The algorithm described in this lesson converts color images to grayscale by calculating a gray level for each pixel and setting the three color channels for that pixel to the value calculated. This effectively converts a color image to grayscale, but it also allows us to add color to image regions, if we wish to do so in the future.

Creating the Image Area

Create a New Mainstack and drag an Image Area onto it. This is the location in which the image will be displayed. Then open the Property Inspector and set the name of the Image Area to Image.

You also have to create the custom property cHiddenImageData for the Image Area. This is used in a subsequent lessons in which it is necessary to have a copy of the image that is being updated.

Creating the Load Image Button

Drag a button onto the new stack. Then open the Property Inspector and change the name of the button to Load Image. Next, open the Script Editor for this button and insert the following code:

on mouseUp
	answer files "Select the image you wish to load:" with type "JPEG Images|jpg|JPEG"
	set the filename of image "Image" to it
	set the cHiddenImageData of image "Image" to the imageData of image "Image"
end mouseUp

This button allows you to open Joint Photographic Experts Group images for processing.

Note: Update the type information in the code if you would like to be able to load other image types too.

Creating the Convert to Grayscale Button

Drag a button onto the new stack. Then open the Property Inspector and change the name of the button to Grayscale. Next, open the Script Editor for this button and insert the following code:

on mouseUp
	local tPixel, tImgPosition, tGray, tImage
	put the imageData of image "Image" into tImage
	# repeat for all the pixels in the image
	repeat with tPixel = 0 to (height of image "Image" * width of image "Image") - 1
		# multiply the image pixel position by 4 (Alpha + Red + Green + Blue) 
		put tPixel * 4 into tImgPosition
		# calculate the gray level - we are using typical weights here
		put 0.30 * charToNum (char (tImgPosition + 2) of tImage) + \
			0.59 * charToNum (char (tImgPosition + 3) of tImage) + \
			0.11 * charToNum (char (tImgPosition + 4) of tImage) into tGray
		# set the RGB of the pixel to the same value this gives us the gray level
		put numToChar (tGray) into char (tImgPosition + 2) of tImage
		put numToChar (tGray) into char (tImgPosition + 3) of tImage
		put numToChar (tGray) into char (tImgPosition + 4) of tImage
	end repeat
	# assign the updated image data back to the displayed image
	set the imageData of image "Image" to tImage
	set the cHiddenImageData of image "Image" to tImage 
end mouseUp

 

Loading an Image

Loading an Image

Your application may look something like the one shown in this example. After selecting the Load Image button you should get a file selection dialog that allows you to select an image from your file system. The image is then displayed in the Image Area.

Processing an Image

Processing an Image

The color image is converted from color to grayscale by selecting the Grayscale button.

Note: Depending on the size of the image and the processing power of  your computer, this may take a few seconds.

7 Comments

Rashad

This does not work for me. I get an error that points out this:

set the filename of image "Image" to it

Hanson Schmidt-Cornelius

Hi Rashad,

set the filename of image "Image" to it

this assumes that an image area with the name "Image" exists on your card. Have a look at the instructions under "Creating the Image Area". You should be able to fix the issue by dragging and dropping an image area from the "Tools" pallet onto the card. The default name of an image area is "Image".

Kind Regards,

Hanson

Ray

Hi Hanson,

I have a few questions regarding the Edge Detection app that you have documented.

(a) I have followed your instructions and created the app, however nothing happens when I start it up .. I do not get the prompt to enter or choose an image filename.

(b) You mention about making a control cHiddenImageData in the Image Area as shown below:

"You also have to create the custom property cHiddenImageData for the Image Area. This is used in a subsequent lessons in which it is necessary to have a copy of the image that is being updated".

However you do not indicate what kind of control it is as well as how to create and embed it into the Image Area.
You also mention about subsequent lessons .. please could you clarify this as well.

Thank you and kind regards .. Ray

Hanson Schmidt-Cornelius

Hi Ray,

The Edge Detection lesson is fundamentally an accumulation of code from a number of lessons. The lesson here being the first one. You also require the code from lessons:
http://lessons.runrev.com/s/lessons/m/4071/l/26580
http://lessons.runrev.com/s/lessons/m/4071/l/26667

Just follow through all three lessons, keep adding the code to your stack and you should get a working edge detection app. You may also have to lock the size and position of the image area in the Property Inspector. This ensures that images do not automatically resize the image area, when they are loaded.

(a) The functionality to load a file is provided in this lesson under "Creating the Load Image Button".

(b) cHiddenImageData is a custom property that is more like a variable that allows you to store data in the "Image" control. So the image area can show a copy of the data you are displaying, but it also stores the cHiddenData. The following line sets up the custom property for you:
set the cHiddenImageData of image "Image" to tImage

I hope this addresses the problem you have been having.

KindRegards,

Hanson

Bob Johnson

How could I make a saturate button?

Hanson Schmidt-Cornelius

Hi Bob,

we do not have a lesson on implementing color saturation. If you would like to implement color saturation, then the algorithm in this lesson provides the information you need to access all the pixels and their ARGB values in an image.

You will have to implement the algorithm for color saturation yourself and then apply the value changes to the relevant pixels in the image you are processing.

Kind Regards,

Hanson

MaxV

You code is too slow, try this one (about 10'000 times faster):

put 0 into cont
repeat for each char tChar in tImage
add 1 to cont
put cont mod 4 into cont2
switch cont2
case 1 #trasparency
put tChar after tImage2
break
case 2 #red
put chartonum(tChar) into rosso
break
case 3 #green
put chartonum(tChar) into verde
break
case 0 #blue
put chartonum(tChar) into blu
#here you can use any grayscale formula
put 0.3 * rosso + 0.59 * verde + 0.11 * blu into tGray
put numToChar(tGray) after tImage2
put numToChar(tGray) after tImage2
put numToChar(tGray) after tImage2
break
end switch
set the imageData of image "Image" to tImage2

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.