how to speed up finding which image pixel color is not in a given color list












1















Purpose: I would like to speed up the process of finding which image pixel value does not contain one of the colors in a given RGB colors table and to map them to another image with _mistakes.png suffix.



Using two for loops to process each pixel individually considering the large size of the image takes long.



import glob
import numpy as np
import os
import cv2
import os.path
# the given list of defined RGB colors.
CLASSES = {
0: [0, 0, 0],
1:[255, 0, 0],
2:[0, 0, 255],
3:[0, 255, 0],
4:[50, 255, 50],
5:[100, 255, 100]
}
for image_path in glob.glob("*.png"):
name = os.path.split(image_path)[-1]
_name = os.path.splitext(name)[0]
img = cv2.imread(image_path)
img_height, img_width, _ = img.shape
img_mistakes = np.zeros((img.shape))

color_codes = np.array(list(CLASSES.values()))

# the following two for loops take so long.
for row in range(img_height):
for col in range(img_width):
if not (img[row,col] == color_codes).all(1).any():
img_mistakes[row, col] = [200, 200, 200] # a chosen color

cv2.imwrite(_name + '_mistakes' + '.png', img_mistakes)









share|improve this question


















  • 1





    Use vectorized numpy operations, instead of iterating over all the pixels in the interpreter. e.g. you can find all the coordinates of pixels of certain colour using a single call to an optimized function (easily 2 orders of magnitude faster than what you do now), and then use the result to set all those pixels to your chosen colour.

    – Dan Mašek
    Jan 1 at 23:44






  • 2





    Also, consider multi-threading the operation and breaking the image down into regions for each thread to work on.

    – PerpetualJ
    Jan 1 at 23:47
















1















Purpose: I would like to speed up the process of finding which image pixel value does not contain one of the colors in a given RGB colors table and to map them to another image with _mistakes.png suffix.



Using two for loops to process each pixel individually considering the large size of the image takes long.



import glob
import numpy as np
import os
import cv2
import os.path
# the given list of defined RGB colors.
CLASSES = {
0: [0, 0, 0],
1:[255, 0, 0],
2:[0, 0, 255],
3:[0, 255, 0],
4:[50, 255, 50],
5:[100, 255, 100]
}
for image_path in glob.glob("*.png"):
name = os.path.split(image_path)[-1]
_name = os.path.splitext(name)[0]
img = cv2.imread(image_path)
img_height, img_width, _ = img.shape
img_mistakes = np.zeros((img.shape))

color_codes = np.array(list(CLASSES.values()))

# the following two for loops take so long.
for row in range(img_height):
for col in range(img_width):
if not (img[row,col] == color_codes).all(1).any():
img_mistakes[row, col] = [200, 200, 200] # a chosen color

cv2.imwrite(_name + '_mistakes' + '.png', img_mistakes)









share|improve this question


















  • 1





    Use vectorized numpy operations, instead of iterating over all the pixels in the interpreter. e.g. you can find all the coordinates of pixels of certain colour using a single call to an optimized function (easily 2 orders of magnitude faster than what you do now), and then use the result to set all those pixels to your chosen colour.

    – Dan Mašek
    Jan 1 at 23:44






  • 2





    Also, consider multi-threading the operation and breaking the image down into regions for each thread to work on.

    – PerpetualJ
    Jan 1 at 23:47














1












1








1


1






Purpose: I would like to speed up the process of finding which image pixel value does not contain one of the colors in a given RGB colors table and to map them to another image with _mistakes.png suffix.



Using two for loops to process each pixel individually considering the large size of the image takes long.



import glob
import numpy as np
import os
import cv2
import os.path
# the given list of defined RGB colors.
CLASSES = {
0: [0, 0, 0],
1:[255, 0, 0],
2:[0, 0, 255],
3:[0, 255, 0],
4:[50, 255, 50],
5:[100, 255, 100]
}
for image_path in glob.glob("*.png"):
name = os.path.split(image_path)[-1]
_name = os.path.splitext(name)[0]
img = cv2.imread(image_path)
img_height, img_width, _ = img.shape
img_mistakes = np.zeros((img.shape))

color_codes = np.array(list(CLASSES.values()))

# the following two for loops take so long.
for row in range(img_height):
for col in range(img_width):
if not (img[row,col] == color_codes).all(1).any():
img_mistakes[row, col] = [200, 200, 200] # a chosen color

cv2.imwrite(_name + '_mistakes' + '.png', img_mistakes)









share|improve this question














Purpose: I would like to speed up the process of finding which image pixel value does not contain one of the colors in a given RGB colors table and to map them to another image with _mistakes.png suffix.



Using two for loops to process each pixel individually considering the large size of the image takes long.



import glob
import numpy as np
import os
import cv2
import os.path
# the given list of defined RGB colors.
CLASSES = {
0: [0, 0, 0],
1:[255, 0, 0],
2:[0, 0, 255],
3:[0, 255, 0],
4:[50, 255, 50],
5:[100, 255, 100]
}
for image_path in glob.glob("*.png"):
name = os.path.split(image_path)[-1]
_name = os.path.splitext(name)[0]
img = cv2.imread(image_path)
img_height, img_width, _ = img.shape
img_mistakes = np.zeros((img.shape))

color_codes = np.array(list(CLASSES.values()))

# the following two for loops take so long.
for row in range(img_height):
for col in range(img_width):
if not (img[row,col] == color_codes).all(1).any():
img_mistakes[row, col] = [200, 200, 200] # a chosen color

cv2.imwrite(_name + '_mistakes' + '.png', img_mistakes)






python image opencv






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 1 at 23:35









Majid AzimiMajid Azimi

4541623




4541623








  • 1





    Use vectorized numpy operations, instead of iterating over all the pixels in the interpreter. e.g. you can find all the coordinates of pixels of certain colour using a single call to an optimized function (easily 2 orders of magnitude faster than what you do now), and then use the result to set all those pixels to your chosen colour.

    – Dan Mašek
    Jan 1 at 23:44






  • 2





    Also, consider multi-threading the operation and breaking the image down into regions for each thread to work on.

    – PerpetualJ
    Jan 1 at 23:47














  • 1





    Use vectorized numpy operations, instead of iterating over all the pixels in the interpreter. e.g. you can find all the coordinates of pixels of certain colour using a single call to an optimized function (easily 2 orders of magnitude faster than what you do now), and then use the result to set all those pixels to your chosen colour.

    – Dan Mašek
    Jan 1 at 23:44






  • 2





    Also, consider multi-threading the operation and breaking the image down into regions for each thread to work on.

    – PerpetualJ
    Jan 1 at 23:47








1




1





Use vectorized numpy operations, instead of iterating over all the pixels in the interpreter. e.g. you can find all the coordinates of pixels of certain colour using a single call to an optimized function (easily 2 orders of magnitude faster than what you do now), and then use the result to set all those pixels to your chosen colour.

– Dan Mašek
Jan 1 at 23:44





Use vectorized numpy operations, instead of iterating over all the pixels in the interpreter. e.g. you can find all the coordinates of pixels of certain colour using a single call to an optimized function (easily 2 orders of magnitude faster than what you do now), and then use the result to set all those pixels to your chosen colour.

– Dan Mašek
Jan 1 at 23:44




2




2





Also, consider multi-threading the operation and breaking the image down into regions for each thread to work on.

– PerpetualJ
Jan 1 at 23:47





Also, consider multi-threading the operation and breaking the image down into regions for each thread to work on.

– PerpetualJ
Jan 1 at 23:47












1 Answer
1






active

oldest

votes


















1














There is probably an even faster way than this , but it's a start! My money is on @divakar to know it - hint, hint ;-)



#!/usr/local/bin/python3
import numpy as np
import cv2

# Open image into numpy array
im=cv2.imread('start.png')

# Work out how one pixel of each colour we are looking for looks
black = [0,0,0]
blue = [255,0,0]
red = [0,0,255]
green = [0,255,0]

# Find all pixels where the 3 RGB values match the sought colour
blacks = np.all(im==black, axis=2)
blues = np.all(im==blue , axis=2)
reds = np.all(im==red , axis=2)
greens = np.all(im==green, axis=2)

# Make empty (black) output array same size as input image
mistakes = np.zeros_like(im)
# Make anything not matching any of our colours into [200,200,200]
mistakes[~(blacks | blues | reds | greens)] = [200,200,200]

# Save result
cv2.imwrite("result.png",mistakes)


start.png



enter image description here



Result:



enter image description here






share|improve this answer


























  • Maybe @hpaulj might know a better way to do this?

    – Mark Setchell
    Jan 7 at 13:58











Your Answer






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: "1"
};
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',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999778%2fhow-to-speed-up-finding-which-image-pixel-color-is-not-in-a-given-color-list%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














There is probably an even faster way than this , but it's a start! My money is on @divakar to know it - hint, hint ;-)



#!/usr/local/bin/python3
import numpy as np
import cv2

# Open image into numpy array
im=cv2.imread('start.png')

# Work out how one pixel of each colour we are looking for looks
black = [0,0,0]
blue = [255,0,0]
red = [0,0,255]
green = [0,255,0]

# Find all pixels where the 3 RGB values match the sought colour
blacks = np.all(im==black, axis=2)
blues = np.all(im==blue , axis=2)
reds = np.all(im==red , axis=2)
greens = np.all(im==green, axis=2)

# Make empty (black) output array same size as input image
mistakes = np.zeros_like(im)
# Make anything not matching any of our colours into [200,200,200]
mistakes[~(blacks | blues | reds | greens)] = [200,200,200]

# Save result
cv2.imwrite("result.png",mistakes)


start.png



enter image description here



Result:



enter image description here






share|improve this answer


























  • Maybe @hpaulj might know a better way to do this?

    – Mark Setchell
    Jan 7 at 13:58
















1














There is probably an even faster way than this , but it's a start! My money is on @divakar to know it - hint, hint ;-)



#!/usr/local/bin/python3
import numpy as np
import cv2

# Open image into numpy array
im=cv2.imread('start.png')

# Work out how one pixel of each colour we are looking for looks
black = [0,0,0]
blue = [255,0,0]
red = [0,0,255]
green = [0,255,0]

# Find all pixels where the 3 RGB values match the sought colour
blacks = np.all(im==black, axis=2)
blues = np.all(im==blue , axis=2)
reds = np.all(im==red , axis=2)
greens = np.all(im==green, axis=2)

# Make empty (black) output array same size as input image
mistakes = np.zeros_like(im)
# Make anything not matching any of our colours into [200,200,200]
mistakes[~(blacks | blues | reds | greens)] = [200,200,200]

# Save result
cv2.imwrite("result.png",mistakes)


start.png



enter image description here



Result:



enter image description here






share|improve this answer


























  • Maybe @hpaulj might know a better way to do this?

    – Mark Setchell
    Jan 7 at 13:58














1












1








1







There is probably an even faster way than this , but it's a start! My money is on @divakar to know it - hint, hint ;-)



#!/usr/local/bin/python3
import numpy as np
import cv2

# Open image into numpy array
im=cv2.imread('start.png')

# Work out how one pixel of each colour we are looking for looks
black = [0,0,0]
blue = [255,0,0]
red = [0,0,255]
green = [0,255,0]

# Find all pixels where the 3 RGB values match the sought colour
blacks = np.all(im==black, axis=2)
blues = np.all(im==blue , axis=2)
reds = np.all(im==red , axis=2)
greens = np.all(im==green, axis=2)

# Make empty (black) output array same size as input image
mistakes = np.zeros_like(im)
# Make anything not matching any of our colours into [200,200,200]
mistakes[~(blacks | blues | reds | greens)] = [200,200,200]

# Save result
cv2.imwrite("result.png",mistakes)


start.png



enter image description here



Result:



enter image description here






share|improve this answer















There is probably an even faster way than this , but it's a start! My money is on @divakar to know it - hint, hint ;-)



#!/usr/local/bin/python3
import numpy as np
import cv2

# Open image into numpy array
im=cv2.imread('start.png')

# Work out how one pixel of each colour we are looking for looks
black = [0,0,0]
blue = [255,0,0]
red = [0,0,255]
green = [0,255,0]

# Find all pixels where the 3 RGB values match the sought colour
blacks = np.all(im==black, axis=2)
blues = np.all(im==blue , axis=2)
reds = np.all(im==red , axis=2)
greens = np.all(im==green, axis=2)

# Make empty (black) output array same size as input image
mistakes = np.zeros_like(im)
# Make anything not matching any of our colours into [200,200,200]
mistakes[~(blacks | blues | reds | greens)] = [200,200,200]

# Save result
cv2.imwrite("result.png",mistakes)


start.png



enter image description here



Result:



enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 2 at 13:19

























answered Jan 2 at 13:07









Mark SetchellMark Setchell

90.6k779181




90.6k779181













  • Maybe @hpaulj might know a better way to do this?

    – Mark Setchell
    Jan 7 at 13:58



















  • Maybe @hpaulj might know a better way to do this?

    – Mark Setchell
    Jan 7 at 13:58

















Maybe @hpaulj might know a better way to do this?

– Mark Setchell
Jan 7 at 13:58





Maybe @hpaulj might know a better way to do this?

– Mark Setchell
Jan 7 at 13:58




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999778%2fhow-to-speed-up-finding-which-image-pixel-color-is-not-in-a-given-color-list%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas