Color image classification and labeling algorithm

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
I have some code I've been using to de-noise some images and then label all unique and contiguous elements. The function zoneMap() de-noises the image by picking a random, unclassified point and then averages all points that are within a certain euclidean distance in color space. This repeats until each point has been classified. The function labelPix() handles the labeling by finding the unique elements in the image processed by zoneMap(), and then labelleing each individual contiguous region.
I am pleased with the output of the functions, however, I would really appreciate any advice on how they can be sped up.
import numpy, random, glob, os,
from skimage import io
def zoneMap(RGB, colorThreshold):
[height, width, _] = RGB.shape
mask = numpy.ones((height, width), dtype = bool)
whiteValues = (RGB == 255).all(-1)
mask[whiteValues] = False
WHITEMASK = mask
pix = RGB.astype(int)
while True in mask:
nextPossible = numpy.argwhere(mask == True)
x, y = nextPossible[random.randint(0, len(nextPossible) - 1)]
point = pix[x, y]
distance = numpy.sqrt(numpy.sum((pix - point)**2, axis = -1))
distance[numpy.invert(mask)] = 500
toAverageCoords = (distance <= colorThreshold)
mask[toAverageCoords] = False
pointsToAverage = pix[toAverageCoords]
average = pointsToAverage.mean(axis = 0)
pix[toAverageCoords] = average
unique, counts = numpy.unique(mask, return_counts=True)
progress = dict(zip(unique, counts))
print('Progress: ', (progress[False]/(height*width))*100, '%')
return pix, WHITEMASK
def labelPix(pix):
height, width, _ = pix.shape
pixRows = numpy.reshape(pix, (height * width, 3))
unique, counts = numpy.unique(pixRows, return_counts = True, axis = 0)
unique = [list(elem) for elem in unique]
del(unique[unique.index(list(pix[0,0]))])
labeledPix = numpy.zeros((height, width), dtype = int)
offset = 0
for index, zoneArray in enumerate(unique):
index += offset
zone = list(zoneArray)
zoneArea = (pix == zone).all(-1)
elementsArray, numElements = scipy.ndimage.label(zoneArea)
elementsArray[elementsArray!=0] += offset
labeledPix[elementsArray!=0] = elementsArray[elementsArray!=0]
offset += numElements
return labeledPix
def main():
file = PATH
im = io.imread(file)
pix = im[:,:,:3]
mapArray, _ = zoneMap(pix, 25)
labeledPix = labelPix(mapArray)
toSave = NEWPATH
io.imsave(toSave, mapArray)
I have been using this on images similar to the one linked, though any image should be suitable as input:
python numpy
add a comment |Â
up vote
4
down vote
favorite
I have some code I've been using to de-noise some images and then label all unique and contiguous elements. The function zoneMap() de-noises the image by picking a random, unclassified point and then averages all points that are within a certain euclidean distance in color space. This repeats until each point has been classified. The function labelPix() handles the labeling by finding the unique elements in the image processed by zoneMap(), and then labelleing each individual contiguous region.
I am pleased with the output of the functions, however, I would really appreciate any advice on how they can be sped up.
import numpy, random, glob, os,
from skimage import io
def zoneMap(RGB, colorThreshold):
[height, width, _] = RGB.shape
mask = numpy.ones((height, width), dtype = bool)
whiteValues = (RGB == 255).all(-1)
mask[whiteValues] = False
WHITEMASK = mask
pix = RGB.astype(int)
while True in mask:
nextPossible = numpy.argwhere(mask == True)
x, y = nextPossible[random.randint(0, len(nextPossible) - 1)]
point = pix[x, y]
distance = numpy.sqrt(numpy.sum((pix - point)**2, axis = -1))
distance[numpy.invert(mask)] = 500
toAverageCoords = (distance <= colorThreshold)
mask[toAverageCoords] = False
pointsToAverage = pix[toAverageCoords]
average = pointsToAverage.mean(axis = 0)
pix[toAverageCoords] = average
unique, counts = numpy.unique(mask, return_counts=True)
progress = dict(zip(unique, counts))
print('Progress: ', (progress[False]/(height*width))*100, '%')
return pix, WHITEMASK
def labelPix(pix):
height, width, _ = pix.shape
pixRows = numpy.reshape(pix, (height * width, 3))
unique, counts = numpy.unique(pixRows, return_counts = True, axis = 0)
unique = [list(elem) for elem in unique]
del(unique[unique.index(list(pix[0,0]))])
labeledPix = numpy.zeros((height, width), dtype = int)
offset = 0
for index, zoneArray in enumerate(unique):
index += offset
zone = list(zoneArray)
zoneArea = (pix == zone).all(-1)
elementsArray, numElements = scipy.ndimage.label(zoneArea)
elementsArray[elementsArray!=0] += offset
labeledPix[elementsArray!=0] = elementsArray[elementsArray!=0]
offset += numElements
return labeledPix
def main():
file = PATH
im = io.imread(file)
pix = im[:,:,:3]
mapArray, _ = zoneMap(pix, 25)
labeledPix = labelPix(mapArray)
toSave = NEWPATH
io.imsave(toSave, mapArray)
I have been using this on images similar to the one linked, though any image should be suitable as input:
python numpy
One small thing to do that will speed up stuff is to usedist = numpy.linalg.norm(a-b)instead ofnumpy.sqrt(numpy.sum((pix - point)**2)
â Oscar Smith
Jan 19 at 5:17
You should edit your title to a description of what your code does, not what you want out of a review. Your current title applies to basically all image processing questions on this site. You might also want to link to your previous question.
â Graipher
Jan 19 at 10:29
thresholdis undefined.
â Georgy
Jan 19 at 19:20
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I have some code I've been using to de-noise some images and then label all unique and contiguous elements. The function zoneMap() de-noises the image by picking a random, unclassified point and then averages all points that are within a certain euclidean distance in color space. This repeats until each point has been classified. The function labelPix() handles the labeling by finding the unique elements in the image processed by zoneMap(), and then labelleing each individual contiguous region.
I am pleased with the output of the functions, however, I would really appreciate any advice on how they can be sped up.
import numpy, random, glob, os,
from skimage import io
def zoneMap(RGB, colorThreshold):
[height, width, _] = RGB.shape
mask = numpy.ones((height, width), dtype = bool)
whiteValues = (RGB == 255).all(-1)
mask[whiteValues] = False
WHITEMASK = mask
pix = RGB.astype(int)
while True in mask:
nextPossible = numpy.argwhere(mask == True)
x, y = nextPossible[random.randint(0, len(nextPossible) - 1)]
point = pix[x, y]
distance = numpy.sqrt(numpy.sum((pix - point)**2, axis = -1))
distance[numpy.invert(mask)] = 500
toAverageCoords = (distance <= colorThreshold)
mask[toAverageCoords] = False
pointsToAverage = pix[toAverageCoords]
average = pointsToAverage.mean(axis = 0)
pix[toAverageCoords] = average
unique, counts = numpy.unique(mask, return_counts=True)
progress = dict(zip(unique, counts))
print('Progress: ', (progress[False]/(height*width))*100, '%')
return pix, WHITEMASK
def labelPix(pix):
height, width, _ = pix.shape
pixRows = numpy.reshape(pix, (height * width, 3))
unique, counts = numpy.unique(pixRows, return_counts = True, axis = 0)
unique = [list(elem) for elem in unique]
del(unique[unique.index(list(pix[0,0]))])
labeledPix = numpy.zeros((height, width), dtype = int)
offset = 0
for index, zoneArray in enumerate(unique):
index += offset
zone = list(zoneArray)
zoneArea = (pix == zone).all(-1)
elementsArray, numElements = scipy.ndimage.label(zoneArea)
elementsArray[elementsArray!=0] += offset
labeledPix[elementsArray!=0] = elementsArray[elementsArray!=0]
offset += numElements
return labeledPix
def main():
file = PATH
im = io.imread(file)
pix = im[:,:,:3]
mapArray, _ = zoneMap(pix, 25)
labeledPix = labelPix(mapArray)
toSave = NEWPATH
io.imsave(toSave, mapArray)
I have been using this on images similar to the one linked, though any image should be suitable as input:
python numpy
I have some code I've been using to de-noise some images and then label all unique and contiguous elements. The function zoneMap() de-noises the image by picking a random, unclassified point and then averages all points that are within a certain euclidean distance in color space. This repeats until each point has been classified. The function labelPix() handles the labeling by finding the unique elements in the image processed by zoneMap(), and then labelleing each individual contiguous region.
I am pleased with the output of the functions, however, I would really appreciate any advice on how they can be sped up.
import numpy, random, glob, os,
from skimage import io
def zoneMap(RGB, colorThreshold):
[height, width, _] = RGB.shape
mask = numpy.ones((height, width), dtype = bool)
whiteValues = (RGB == 255).all(-1)
mask[whiteValues] = False
WHITEMASK = mask
pix = RGB.astype(int)
while True in mask:
nextPossible = numpy.argwhere(mask == True)
x, y = nextPossible[random.randint(0, len(nextPossible) - 1)]
point = pix[x, y]
distance = numpy.sqrt(numpy.sum((pix - point)**2, axis = -1))
distance[numpy.invert(mask)] = 500
toAverageCoords = (distance <= colorThreshold)
mask[toAverageCoords] = False
pointsToAverage = pix[toAverageCoords]
average = pointsToAverage.mean(axis = 0)
pix[toAverageCoords] = average
unique, counts = numpy.unique(mask, return_counts=True)
progress = dict(zip(unique, counts))
print('Progress: ', (progress[False]/(height*width))*100, '%')
return pix, WHITEMASK
def labelPix(pix):
height, width, _ = pix.shape
pixRows = numpy.reshape(pix, (height * width, 3))
unique, counts = numpy.unique(pixRows, return_counts = True, axis = 0)
unique = [list(elem) for elem in unique]
del(unique[unique.index(list(pix[0,0]))])
labeledPix = numpy.zeros((height, width), dtype = int)
offset = 0
for index, zoneArray in enumerate(unique):
index += offset
zone = list(zoneArray)
zoneArea = (pix == zone).all(-1)
elementsArray, numElements = scipy.ndimage.label(zoneArea)
elementsArray[elementsArray!=0] += offset
labeledPix[elementsArray!=0] = elementsArray[elementsArray!=0]
offset += numElements
return labeledPix
def main():
file = PATH
im = io.imread(file)
pix = im[:,:,:3]
mapArray, _ = zoneMap(pix, 25)
labeledPix = labelPix(mapArray)
toSave = NEWPATH
io.imsave(toSave, mapArray)
I have been using this on images similar to the one linked, though any image should be suitable as input:
python numpy
edited Jan 20 at 3:21
Jamalâ¦
30.1k11114225
30.1k11114225
asked Jan 18 at 22:30
asheets
413
413
One small thing to do that will speed up stuff is to usedist = numpy.linalg.norm(a-b)instead ofnumpy.sqrt(numpy.sum((pix - point)**2)
â Oscar Smith
Jan 19 at 5:17
You should edit your title to a description of what your code does, not what you want out of a review. Your current title applies to basically all image processing questions on this site. You might also want to link to your previous question.
â Graipher
Jan 19 at 10:29
thresholdis undefined.
â Georgy
Jan 19 at 19:20
add a comment |Â
One small thing to do that will speed up stuff is to usedist = numpy.linalg.norm(a-b)instead ofnumpy.sqrt(numpy.sum((pix - point)**2)
â Oscar Smith
Jan 19 at 5:17
You should edit your title to a description of what your code does, not what you want out of a review. Your current title applies to basically all image processing questions on this site. You might also want to link to your previous question.
â Graipher
Jan 19 at 10:29
thresholdis undefined.
â Georgy
Jan 19 at 19:20
One small thing to do that will speed up stuff is to use
dist = numpy.linalg.norm(a-b) instead of numpy.sqrt(numpy.sum((pix - point)**2)â Oscar Smith
Jan 19 at 5:17
One small thing to do that will speed up stuff is to use
dist = numpy.linalg.norm(a-b) instead of numpy.sqrt(numpy.sum((pix - point)**2)â Oscar Smith
Jan 19 at 5:17
You should edit your title to a description of what your code does, not what you want out of a review. Your current title applies to basically all image processing questions on this site. You might also want to link to your previous question.
â Graipher
Jan 19 at 10:29
You should edit your title to a description of what your code does, not what you want out of a review. Your current title applies to basically all image processing questions on this site. You might also want to link to your previous question.
â Graipher
Jan 19 at 10:29
threshold is undefined.â Georgy
Jan 19 at 19:20
threshold is undefined.â Georgy
Jan 19 at 19:20
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185434%2fcolor-image-classification-and-labeling-algorithm%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password

One small thing to do that will speed up stuff is to use
dist = numpy.linalg.norm(a-b)instead ofnumpy.sqrt(numpy.sum((pix - point)**2)â Oscar Smith
Jan 19 at 5:17
You should edit your title to a description of what your code does, not what you want out of a review. Your current title applies to basically all image processing questions on this site. You might also want to link to your previous question.
â Graipher
Jan 19 at 10:29
thresholdis undefined.â Georgy
Jan 19 at 19:20