Color image classification and labeling algorithm

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite
1












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:




enter image description here








share|improve this question





















  • 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











  • threshold is undefined.
    – Georgy
    Jan 19 at 19:20
















up vote
4
down vote

favorite
1












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:




enter image description here








share|improve this question





















  • 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











  • threshold is undefined.
    – Georgy
    Jan 19 at 19:20












up vote
4
down vote

favorite
1









up vote
4
down vote

favorite
1






1





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:




enter image description here








share|improve this question













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:




enter image description here










share|improve this question












share|improve this question




share|improve this question








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 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











  • threshold is 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










  • 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















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















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















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



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














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













































































Popular posts from this blog

Python Lists

Aion

JavaScript Array Iteration Methods