# need to find red zones out of 9 zones in the img from PIL import Image, ImageFont, ImageDraw import math def getRedZones(imgPath): img = Image.open(imgPath) pixelValues = list(img.getdata()) # colors = img.getcolors() # print("colors: ", colors) print("totalPixels: ", len(pixelValues)) # print("pixelValues: ", pixelValues[:1000]) # for i in range(len(pixelValues)): # pixelData = pixelValues[i] # if pixelData[3] == 255: # print(i, pixelData) # return # return imgSize = img.size # w-h print("imgSize: ", imgSize) imgWidth = imgSize[0] imgHeight = imgSize[1] zoneWidth = imgWidth/3 zoneHeight = imgHeight/3 redZoneMatrix = {} fieldAreaMatrix = {} for i in range(9): addZoneToRawMatixIfNone(redZoneMatrix, i+1) fieldAreaMatrix[i+1] = 0 for x in range(imgWidth): for y in range(imgHeight): zoneCol = math.ceil((x+1)/zoneWidth) zoneRow = math.ceil((y+1)/zoneHeight) zoneNo = (zoneRow-1)*3 + zoneCol isLeftInZone = getIsLeftZone(zoneNo, x, y, imgWidth, imgHeight) # assuming it to be tuple of rgba pixelData = pixelValues[y*imgWidth + x] isFieldPixel = pixelData[3] == 255 isRedZonePixel = findIfRedZonePixel(pixelData) if isRedZonePixel: # addZoneToRawMatixIfNone(redZoneRawMatrix, zoneNo) redZoneMatrix[zoneNo]['total'] += 1 redZoneMatrix[zoneNo]['left' if isLeftInZone else 'right'] += 1 if isFieldPixel: if zoneNo not in fieldAreaMatrix: fieldAreaMatrix[zoneNo] = 0 fieldAreaMatrix[zoneNo] += 1 print("redZones: ", redZoneMatrix) print("zoneAreas: ", fieldAreaMatrix) # get redZoneMatrix from raw totalFieldArea = sum(fieldAreaMatrix.values()) print("zoneAreaSum: ", totalFieldArea) for zoneNo, redCount in redZoneMatrix.items(): if zoneNo != 5 and (fieldAreaMatrix[zoneNo] or 0) < 0.02*totalFieldArea: # shift this zone's redCount to adjecent zones leftZoneNo = getAdjecentZoneNo(zoneNo, True) # addZoneToRawMatixIfNone(redZoneRawMatrix, leftZoneNo, fieldAreaMatrix, 0.02*totalFieldArea) redZoneMatrix[leftZoneNo]["total"] += redCount["left"] redZoneMatrix[leftZoneNo]["right"] += redCount["left"] rightZoneNo = getAdjecentZoneNo(zoneNo, False) # addZoneToRawMatixIfNone(redZoneRawMatrix, rightZoneNo, fieldAreaMatrix, 0.02*totalFieldArea) redZoneMatrix[rightZoneNo]["total"] += redCount["right"] redZoneMatrix[rightZoneNo]["right"] += redCount["right"] print("totalRedArea: ", sum(map(returnZoneTotal, redZoneMatrix.values()))) redZones = [] for i in range(9): if redZoneMatrix[i+1]["total"] > 0.04*totalFieldArea: redZones.append(i+1) return redZones def returnZoneTotal(zoneData): return zoneData["total"] zoneOrder = [1, 2, 3, 6, 9, 8, 7, 4] def getAdjecentZoneNo(zoneNo, isLeft, areaMatrix, minArea): zone = zoneOrder[(zoneNo-1+(-1 if isLeft else 1)) % 8] if (areaMatrix[zone] or 0) < minArea: zone = getAdjecentZoneNo(zone, isLeft, areaMatrix, minArea) return zone def getIsLeftZone(zoneNo, x, y, imgWidth, imgHeight): if zoneNo == 2: return x < imgWidth/2 if zoneNo == 6: return y < imgHeight/2 if zoneNo == 8: return x > imgWidth/2 if zoneNo == 4: return y > imgHeight/2 if zoneNo == 1: return y > x*imgHeight/imgWidth if zoneNo == 3: return y < (imgWidth-x)*imgHeight/imgWidth if zoneNo == 9: return (imgHeight-y) > (imgWidth-x)*imgHeight/imgWidth if zoneNo == 7: return (imgHeight-y) < x*imgHeight/imgWidth def addZoneToRawMatixIfNone(matrix, zoneNo): if zoneNo not in matrix: matrix[zoneNo] = {'total': 0, 'left': 0, 'right': 0} # (255, 240, 179, 255), redPixels = [(251, 193, 126, 255), (247, 137, 89, 255), (234, 77, 57, 255), (173, 5, 53, 255)] def findIfRedZonePixel(pixelData): for redPixelData in redPixels: if abs(sum(redPixelData)-sum(pixelData)) < 10: return True return False def getInstructionsByZones(redZones, translations, isIrri): result = "%s- %s" % (translations['forCropProbInstruc' if not isIrri else 'forIrriProbInstruc'], ", ".join(map(zoneToStr, redZones))) return result def zoneToStr(zoneNo): if zoneNo == 1: return "NW" if zoneNo == 2: return "N" if zoneNo == 3: return "NE" if zoneNo == 4: return "W" if zoneNo == 5: return "C" if zoneNo == 6: return "E" if zoneNo == 7: return "SW" if zoneNo == 8: return "S" if zoneNo == 9: return "SE" # imgPath = "field_img6.png" #"sampleField.png" # redZones = getRedZones(imgPath) # print(redZones) # 299-E61919, 60-3D1362, 17-11A75E, 247-F78959, 145-93102D #186, 227, 131-B9E382,12182402,12247939; # create field dirc img def createFieldDirImg(imgPath, savePath="dirImg.png"): img = Image.open(imgPath) imgWidth = img.size[0] imgHeight = img.size[1] # make single color img pixelMap = img.load() for x in range(imgWidth): for y in range(imgHeight): if 0 == pixelMap[x, y][3]: pixelMap[x, y] = (255, 255, 255, 0) else: pixelMap[x, y] = (255, 240, 179, 255) # resize if needed smallerLen = min(imgWidth, imgHeight) factor = 1 if smallerLen < 300: factor = round(300/smallerLen, 1) if factor % 0.2 == 0.1: factor += 0.1 if factor != 1: img = img.resize((round(imgWidth*factor), round(imgHeight*factor))) imgHeight = img.size[1] imgWidth = img.size[0] # add zone lines editableImg = ImageDraw.Draw(img) width1 = round(imgWidth/3) width2 = round(imgWidth*2/3) height1 = round(imgHeight/3) height2 = round(imgHeight*2/3) editableImg.line([(width1, 0), (width1, imgHeight)], (0, 0, 0), 2) editableImg.line([(width2, 0), (width2, imgHeight)], (0, 0, 0), 2) editableImg.line([(0, height1), (imgWidth, height1)], (0, 0, 0), 2) editableImg.line([(0, height2), (imgWidth, height2)], (0, 0, 0), 2) # add direction text fontSize = 50 font = ImageFont.truetype("report_fonts/Noto_Sans/NotoSans-Bold.ttf", fontSize) widthF = round((width1-80)/2) heightF = round((height1-100)/2) editableImg.text((widthF, heightF), "NW", (255, 50, 36), font) editableImg.text((width1+widthF, heightF), "N", (255, 50, 36), font) editableImg.text((width2+widthF, heightF), "NE", (255, 50, 36), font) editableImg.text((widthF, height1+heightF), "W", (255, 50, 36), font) editableImg.text((width1+widthF, height1+heightF), "C", (255, 50, 36), font) editableImg.text((width2+widthF, height1+heightF), "E", (255, 50, 36), font) editableImg.text((widthF, height2+heightF), "SW", (255, 50, 36), font) editableImg.text((width1+widthF, height2+heightF), "S", (255, 50, 36), font) editableImg.text((width2+widthF, height2+heightF), "SE", (255, 50, 36), font) # save the result img.save(savePath) # createFieldDirImg(imgPath) # print("done")