Search code examples
pythonopencvmachine-learningscikit-image

Find average colour of each section of an image


I am looking for the best way to achieve the following using Python:

  1. Import an image.
  2. Add a grid of n sections (4 shown in this example below).
  3. For each section find the dominant colour.

sky

Desired output

Output an array, list, dict or similar capturing these dominant colour values.

Maybe even a Matplotlib graph showing the colours (like pixel art).

What have I tried?

The image could be sliced using image slicer:

import image_slicer
image_slicer.slice('image_so_grid.png', 4)

I could then potentially use something like this to get the average colour but Im sure there are better ways to do this.

What are the best ways to do this with Python?


Solution

  • This works for 4 sections, but you'll need to figure out how to make it work for 'n' sections:

    import cv2
    
    img = cv2.imread('image.png')
    
    def fourSectionAvgColor(image):
        rows, cols, ch = image.shape
        colsMid = int(cols/2)
        rowsMid = int(rows/2)
    
        numSections = 4
        section0 = image[0:rowsMid, 0:colsMid]
        section1 = image[0:rowsMid, colsMid:cols]
        section2 = image[rowsMid: rows, 0:colsMid]
        section3 = image[rowsMid:rows, colsMid:cols]
        sectionsList = [section0, section1, section2, section3]
    
        sectionAvgColorList = []
        for i in sectionsList:
            pixelSum = 0
            yRows, xCols, chs = i.shape
            pixelCount = yRows*xCols
            totRed = 0
            totBlue = 0
            totGreen = 0
            for x in range(xCols):
                for y in range(yRows):
                    bgr = i[y,x]
                    b = bgr[0]
                    g = bgr[1]
                    r = bgr[2]
                    totBlue = totBlue+b
                    totGreen = totGreen+g
                    totRed = totRed+r
    
            avgBlue = int(totBlue/pixelCount)
            avgGreen = int(totGreen/pixelCount)
            avgRed = int(totRed/pixelCount)
            avgPixel = (avgBlue, avgGreen, avgRed)
            sectionAvgColorList.append(avgPixel)
        return sectionAvgColorList
    
    print(fourSectionAvgColor(img))
    cv2.waitKey(0)
    cv2.destroyAllWindows()