简体   繁体   中英

How to merge pixels WITHIN an image based on their rgb values in python?

So far , I've divided an image into blocks of specific size and these blocks have the mean color of the original block. Now, I have to merge these blocks based on their similarity, where each block contains a single pixel value(mean color value). For this , I have been trying to merge pixels within an image based on their rgb values. So far I've not found anything that would help me with this. So kindly help me to solve this problem. What I've done so far...

x and y are the block sizes. Here x=y=16.

Input : Original Image Output: Processed image I've not implemented anything after this since I don't know how to proceed further. Now I've to group the pixels in the processed image based on their similarity.

i=0
j=0
m=16
n=16

l=[]   
data = np.zeros( (256,256,3), dtype=np.uint8 )
while(m<=256):
    while(n<=256):
        l=image[i:m,j:n]

        print(l)
        r=0
        g=0
        b=0
        for q in range(len(l)):
            for w in range(len(l)):
                r=r+l[q][w][0]
                g=g+l[q][w][1]
                b=b+l[q][w][2]

        r=r/(x*y)
        b=b/(x*y)
        g=g/(x*y)
        k=[r,g,b]
        data[i:m,j:n]=k
        j=j+16
        n=n+16

    i=i+16
    m=m+16
    j=0
    n=16
img = smp.toimage( data )
data1 = np.asarray( img, dtype="int32" )


cv2.imwrite(os.path.join('G:/AI package/datasets/_normalized',filename),data1)

You have used quite a lot of code to get the first step done, However, the same output can be achieved using numpy functions within 2-3 lines of code as:

import cv2
import numpy as np


def get_mean_color(box):
    return int(np.mean(box[:, :, 0])), int(np.mean(box[:, :, 1])), int(np.mean(box[:, :, 2]))


def get_super_square_pixels(img, super_pix_width):
    height, width, ch = img.shape

    if height % super_pix_width != 0:
        raise Exception("height must be multiple of super pixel width")

    if width % super_pix_width != 0:
        raise Exception("width must be multiple of super pixel width")

    output_img = np.zeros(img.shape, np.uint8)
    for i in xrange(height / super_pix_width):
        for j in xrange(width / super_pix_width):
            src_box = img[i * super_pix_width:(i + 1) * super_pix_width, j * super_pix_width:(j + 1) * super_pix_width]
            mean_val = get_mean_color(src_box)

            output_img[i * super_pix_width:(i + 1) * super_pix_width, j * super_pix_width:(j + 1) * super_pix_width] = mean_val

    return output_img

img = cv2.imread("/path/to/your/img.jpg")
out = get_super_square_pixels(img, 16)

My code may not be optimal but it works just fine.

import cv2
import numpy as np
import scipy.misc as smp
import os


l=[]   
res = np.zeros( (256,256,3), dtype=np.uint8 )
while(m<=256):
    while(n<=256):
        l=image[i:m,j:n][0][0]
        low=np.array([l[0] - thresh, l[1] - thresh, l[2] - thresh])
        high=np.array([l[0] + thresh, l[1] + thresh, l[2] + thresh])
        mask1=cv2.inRange(image,low,high)
        res = cv2.bitwise_and(image, image, mask = mask1)
        block=0
        a=i
        b=j
        c=m
        d=n
        k=[]
        b=b+x
        d=d+x
        while(b<256 and d<256):
            k=res[a:c,b:d][0][0]
            black=[0,0,0]
            while((k!=black).all() and b<256 and d<256):
                block=block+1
                b=b+x
                d=d+x
                k=res[a:c,b:d][0][0]
            image[i:m,j+x:(n+((block)*x))]=l
            break
        j=j+x
        n=n+y

    i=i+x
    m=m+y
    j=0
    n=x
image= cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
img = smp.toimage( image )
data1 = np.asarray( img, dtype="int32" )
cv2.imwrite(os.path.join('G:/AI package/datasets/btob/',filename),data1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM