Getting selection of faces which in it's UV canvas contain only white pixels

Hi,
I’m struggling with this for a while and I can’t get what’s wrong
So… What I’m trying to do:

1.Get face’s UV
2.Scan canvas to check if every texture’s pixel is white
3.If is not then do not select face.

I done some research and found a few things then I customized it for my purposes, so now
I’m able to get correct canvas pixels (canvas of face’s UV) to look up for black color but then magic happens and I get results like in the pictures below :frowning:

Do you have any tips, thanks for any help.


cegly256_depth
And here blend file
select_pixel_by_face_colour.blend (2.3 MB)

import bpy
import math
from math import floor, ceil
from mathutils import Vector
from mathutils.interpolate import poly_3d_calc
from bpy.types import Scene, Mesh, MeshPolygon, Image


#Used when uv coordinate <1 or >1 
def emod(n, m):
    return ((n % m) + m) % m;

#returns ceil(face's top left corner texture's pixel coords) and ceil(face's bottom right corner texture's pixel coords)
def canvasLookup(img,tl,br):
    #print(tl,br)
    #print(emod(tl[0], 1))
    tx1 = (min(emod(tl[0], 1) * img.size[0] , img.size[0]))
    ty1 = (min(emod(tl[1], 1) * img.size[0], img.size[0]))
    tx2 = (min(emod(br[0], 1) * img.size[0] , img.size[0]))
    ty2 = (min(emod(br[1], 1) * img.size[0], img.size[0]))
    tx1 = int(floor(tx1))
    tx2 = int(ceil(tx2))
    ty1 = int(ceil(ty1))
    ty2 = int(floor(ty2))
    return(tx1,ty1,tx2,ty2)

#Searches u or v line of texture's pixels to find if
#it has intersection with rgb != (1,1,1) then return false
def sideLookup(uv_pixels,i,x1,x2): 
    select = False
    for j in range(min(x1,x2),max(x1,x2)+1):
        a,b,c = (uv_pixels[i*j*4+0],uv_pixels[i*j*4+1],uv_pixels[i*j*4+2])
        #print(a,b,c)
        if(a != 1 and b != 1 and c != 1):
            select = False
            break
        else:
            select = True
            break
    return select

#Searches canvas of face - if it has brack intersection
#if any side of pixels has then return(DO NOT SELECT FACE) 
def getSelect(img, x1,y1,x2,y2):
    uv_pixels = img.pixels # Accessing pixels directly is quite slow. Copy to new array and pass as an argument for massive performance-gain if you plan to run this function many times on the same image (img.pixels[:]).
    select = sideLookup(uv_pixels,max(y1,y2),x1,x2)       #top line of pixels
    if(select != True):
        return(False)
    select2 = sideLookup(uv_pixels,min(y1,y2),x1,x2)       #bottom line of pixels
    if(select != True):
        return(False)
    select3 = sideLookup(uv_pixels,min(x1,x2)+1,y1,y2-1)   #left line of pixels w/o first and last from top line
    if(select != True):
        return(False)
    select4 = sideLookup(uv_pixels,max(x1,x2)+1,y1,y2-1)   #right line of pixels w/o first and last from bottom line
    if(select != True):
        return(False)       
    return(True)

def pixelColor_select(polyCount,img):
    
    img_size = 256
    obj = bpy.context.object
    mesh = obj.data
    point = bpy.context.scene.cursor.location
    face_idx = obj.closest_point_on_mesh(point)[-1]
    ob = bpy.context.active_object
    
    face_tl_br = []
    face_index = 0
    #this loop is that I got from forum somwhere
    for face in ob.data.polygons:
        if(face_index == polyCount):
            break
        for vert_idx, loop_idx in zip(face.vertices, face.loop_indices):
            uv_coords = ob.data.uv_layers.active.data[loop_idx].uv
            #print("face idx: %i, vert idx: %i, uvs: %f, %f" % (face.index, vert_idx, uv_coords.x, uv_coords.y))
            face_tl_br.append((uv_coords.x, uv_coords.y))
            
            
        #here you can see that it picks up vertexes clock-wise
        #starting with bottom-left vertex of face
        #for i in range(0,4):
            #print(face_tl_br[i][0]*100,face_tl_br[i][1]*100)
        
            
        a,b,c,d = canvasLookup(img,face_tl_br[1],face_tl_br[3]) #as above - take top left and bottom right pos of vert
        if(a==256):
            a=1;
        if(b==256):
            b=1;
        if(c==256):
            c=1;
        if(d==256):
            d=1;
            
        #print(a,b,c,d)
        #here I assume that I'm in (U>0,V>0) quarter
        boo = getSelect(img,a,b,c,d)
        # min(b,d)%256,max(b,d)%256,min(a,c)%256,max(a,c)%256)
        
        face.select = boo
        print(face_index)
        face_index+=1
        face_tl_br = []
            
            
    
polyCount = 20000
img = bpy.data.images.get("cegly256_depth.png")
pixelColor_select(polyCount,img)

print("DONE")