Python Forum
What is the best way to search for a pixel in a screenshot?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What is the best way to search for a pixel in a screenshot?
#1
I'm trying to find the most efficient way to iterate over a numpy array representing an OpenCV image and to return the location of the first pixel of a given color.
I tried two methods running the same function:
one in python
def get_location(screenshot):
    height = screenshot.shape[0]
    width = screenshot.shape[1]
    for pixel_height in range(height):
        for pixel_width in range(width):
            pixel = screenshot[pixel_height, pixel_width]
            if numpy.array_equal(pixel, WINNER_COLOR):
                return True
    return False
one in cython
@cython.boundscheck(False)
cpdef tuple get_location(unsigned char [:, :, :] screenshot):
    cdef int height, width, pixel_height, pixel_width
    height = screenshot.shape[0]
    width = screenshot.shape[1]
    for pixel_height in range(height):
        for pixel_width in range(width):
            pixel = screenshot[pixel_height, pixel_width]
            if numpy.array_equal(pixel, WINNER_COLOR):
                return True
    return ()
I cut the screenshot to parts and started a process pool with those cuts
screen = cv2.cvtColor(numpy.array(getRectAsImage(SCREEN_RECT)), cv2.COLOR_RGB2BGR)
height, width, depth = screen.shape
screen_cuts = []
for height_cut_index in range(CUTS):
    start_height = int(height / CUTS) * height_cut_index
    end_height = int(height / CUTS) * (height_cut_index + 1)
    for width_cut_index in range(CUTS):
        start_width = int(width / CUTS) * width_cut_index
        end_width = int(width / CUTS) * (width_cut_index + 1)
        cut = screen[start_width:end_width, start_height:end_height]
        screen_cuts.append(cut)
pool.map(get_location, screen_cuts)
I have two main problems; The first is that the python code is faster (1 second) compared to the cython code (3 seconds) for some reason; The second is that it is still too slow, is there a way to speed it up?
Reply
#2
I would recommend the follwoing approach instead of using loops directly:
# image.shape = (height, width, colors)
# pixel = np.array([R, G, B]), i.e.numpy array of length <the number of colors>
# threshold -- scalar value, takes into account color similarity 
np.where((np.abs(pixel - image) < threshold).all(axis=-1))
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Voxel to pixel graphics voicemail 3 533 Nov-19-2023, 09:45 AM
Last Post: paul18fr
  Pixel color and action Sartre 4 1,970 Apr-13-2023, 03:26 AM
Last Post: Sartre
  Dynamic pixel display jerryf 2 675 Mar-17-2023, 07:26 PM
Last Post: jerryf
  Plotting Pixel Intensity Doev 0 1,703 Oct-21-2020, 10:56 PM
Last Post: Doev
  IEDriverServer screenshot ABVSVL 0 1,695 Jul-12-2020, 09:31 AM
Last Post: ABVSVL
  pyautogui.screenshot region is not working alexlu 6 6,385 Jun-04-2020, 10:46 AM
Last Post: alexlu
  Want to take a Screenshot from a File in Linux dhiliptcs 2 2,518 Oct-21-2019, 01:22 PM
Last Post: dhiliptcs
  Fast get pixel and oparate. storzo 7 6,980 Aug-26-2019, 07:36 PM
Last Post: Larz60+
  Screenshot of specific window kainev 10 19,125 Nov-30-2018, 03:07 PM
Last Post: kainev
  datetime with every screenshot name evilcode1 7 5,430 Aug-27-2018, 06:01 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020