1

Using python (openCV2, tkinter etc) I've created an app (a very amateur one) to change blue pixels to white. The images are high quality jpgs or PNGS.

The process: Search every pixel of an image and if the 'b' value of BGR is higher than x, set pixel to white (255, 255, 255).

The problem: There are about 150 pictures to process at a time, so the above process takes quite long. It's around 9 - 15 seconds per iteration depending on the images size (resizing the image speeds up the process, but not ideal).

Here is the code (with GUI and exception handling elements removed for simplicity):

for filename in listdir(sourcefolder):
        # Read image and set variables 
        frame = imread(sourcefolder+"/"+filename)
        rows = frame.shape[0]
        cols = frame.shape[1]

        # Search pixels. If blue, set to white. 
        for i in range(0,rows):
            for j in range(0,cols):
                if frame.item(i,j,0) > 155:
                    frame.itemset((i,j,0),255)
                    frame.itemset((i,j,1),255)
                    frame.itemset((i,j,2),255)
        imwrite(sourcecopy+"/"+filename, frame)
        #release image from memory 
        del frame     

Any help on increasing efficiency / speed would be greatly appreciated!

Dayaan Salie
  • 21
  • 1
  • 6
  • 1
    You could use numpy's [where()](https://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html) method instead of your quadratic loop – T A Dec 04 '19 at 15:57
  • 1
    Maybe you don't have to access pixels like that in python try : img_bgr[mask > x] = [255, 0, 0] – Ziri Dec 04 '19 at 16:10

2 Answers2

5

Start with this image:

enter image description here

Then use this:

import cv2
im = cv2.imread('a.png') 

# Make all pixels where Blue > 150 into white
im[im[...,0]>150] = [255,255,255]

# Save result
cv2.imwrite('result.png', im)

enter image description here

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Brilliant! Thanks so much. Iterations are down to 0.8 seconds. I'm astonished at the simplicity of the code as well. Are all the pixels accessed simultaneously? I guess my amateur instincts is to do exhaustive iteration. Thanks again. – Dayaan Salie Dec 04 '19 at 19:32
  • 2
    We are all amateurs compared to some folk - main thing is to try to keep learning :-) It uses Numpy underneath and is all heavily optimised for us. – Mark Setchell Dec 04 '19 at 19:34
  • Should `result.png` exist before `cv2` can write to it? – Mehdi Charife Jun 06 '23 at 00:18
  • @MehdiCharife It doesn't matter if it exists or not - it will get written either way. – Mark Setchell Jun 06 '23 at 06:01
  • @MarkSetchell I tried doing the equivalent to a video file (by using the `VideoWriter` class but it kept giving me errors creating the file before hand with the `open` function (using `x` as the option) solved the problem So I assumed a similar issue would be in images – Mehdi Charife Jun 06 '23 at 10:15
2

Use cv2.threshold to create a mask using x threshold value.

Set the color like this : img_bgr[mask == 255] = [255, 0, 0]

Ziri
  • 718
  • 7
  • 16