Request for help with Image color space conversion
Question posted by: ttest
(Guest)
on
January 4th, 2008 11:25 PM
Hello,
I'm working on an image processing project using the Python Imaging
Library along with numpy. Right now, I'm trying to build a speedy
script for converting whole images between the RGB and the HSV (a.k.a.
HSB) color spaces. Unfortunately, the code I've made so far runs
dreadfully slow with even moderate-sized images.
I'm under the impression that the crux of the problem is the fact that
PIL's point method operates on only one band at a time, and to do a
proper color space conversion, you need information about all three
bands in a particular problem. This has forced me to do an awkward
work-around where the image data is loaded into a numpy array
(1600x1200x3), and a dinky for-loop run runs through the array picking
up RGB values, converting to HSV, and dumping the results back into
another array.
How can I make this more efficient?
--------
from PIL import Image
from PIL import TiffImagePlugin
from scipy.misc import pilutil
import numpy
import colorsys
def myrgbtohsv(r,g,b):
'''A wrapper for the colorsys function rgb_to_hsv
that takes r,g,b values between 0 and 255
(standard pixel value range in most of my single-band imaging
operations)
and returns the corresponding 255-scaled h,s,v values'''
tr = r/255.0
tg = g/255.0
tb = b/255.0
ur,ug,ub = colorsys.rgb_to_hsv(tr,tg,tb)
pr = int(round(ur,0))*255
pg = int(round(ug,0))*255
pb = int(round(ub,0))*255
return pr,pg,pb
def rgbarrtohsvarr(pilarray):
'''Takes an 3d numpy ndarray loaded with a RGB PIL image and
converts
a copy of the contents to 255-scaled HSV array.
Returns the converted copy of the array.
'''
arrt = pilarray.copy()
r,c,d = arrt.shape
hsvarray = numpy.zeros((r,c,d))
print out
for i in range(0,r):
for j in range(0,c):
localrgb = (arrt[i,j,0],arrt[i,j,1],arrt[i,j,2])
(lh,ls,lv) = rgbtohsv(localrgb)
hsvarray[i,j,0],hsvarray[i,j,1],hsvarray[i,j,2]= lh,ls,lv
return hsvarray
im = Image.open(r'C:\test.tif')
arr = pilutil.fromimage(im)
out = rgbarrtohsvarr(arr)
--------
4
Answers Posted
ttest wrote:
Quote:
Originally Posted by
Hello,
>
I'm working on an image processing project using the Python Imaging
Library along with numpy. Right now, I'm trying to build a speedy
script for converting whole images between the RGB and the HSV (a.k.a.
HSB) color spaces. Unfortunately, the code I've made so far runs
dreadfully slow with even moderate-sized images.
>
I'm under the impression that the crux of the problem is the fact that
PIL's point method operates on only one band at a time, and to do a
proper color space conversion, you need information about all three
bands in a particular problem. This has forced me to do an awkward
work-around where the image data is loaded into a numpy array
(1600x1200x3), and a dinky for-loop run runs through the array picking
up RGB values, converting to HSV, and dumping the results back into
another array.
>
How can I make this more efficient?
Reimplement colorsys.rgb_to_hsv() such that it operates on arrays instead of
scalars. Only minor modifications are necessary.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
Reimplement colorsys.rgb_to_hsv() such that it operates on arrays instead of
Quote:
Originally Posted by
scalars. Only minor modifications are necessary.
>
--
Robert Kern
Thanks! I'll try and see if a newcomer like me can get his head
around the array-centric modifications to colorsys.
ttest wrote:
Quote:
Originally Posted by
Quote:
Originally Posted by
>Reimplement colorsys.rgb_to_hsv() such that it operates on arrays instead of
>scalars. Only minor modifications are necessary.
>>
>--
>Robert Kern
>
Thanks! I'll try and see if a newcomer like me can get his head
around the array-centric modifications to colorsys.
If you hit any roadblocks, drop in on numpy-discussion, and we'll help you out.
http://www.scipy.org/Mailing_Lists
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
>
Quote:
Originally Posted by
...where the image data is loaded into a numpy array
(1600x1200x3)...
One comment: that is a big array, too big for the cache memory. I know
that in these cases it makes a difference how many times the slices of
the array are loaded and unloaded from RAM onto cache. One issue is
that a 2D array l[i,j] is actually a 1D array:
either
l[i,j]=l[i*N+j]
or
l[i,j]=l[j*N+i]
I don't know which in python/numpy. In the first case, when you fix i
and change j, you get consecutive positions in the underlying 1D
array, and they all belong to the same slice, which is loaded onto
cache very fast as a block. If you do the opposite, you are making
jumps to distant positions in the array (not a slice), and performance
suffers.
In gimp, for example, the underlying array is split into 'tiles',
which are 64x64 pixel regions that can be loaded/unloaded as a block.
And that's about all I know on the issue.
So it ma
|
|
|
What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 197,050 network members.
Top Community Contributors
|