# need to find red zones out of 9 zones in the img from PIL import Image, ImageFont, ImageDraw import math def getRedZones(imgPath, isCmap2=False): 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, isCmap2) 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) minArea = 0.02*totalFieldArea for zoneNo, redCount in redZoneMatrix.items(): if zoneNo != 5 and (fieldAreaMatrix[zoneNo] or 0) < minArea: # shift this zone's redCount to adjecent zones leftZoneNo = getAdjecentZoneNo( zoneNo, True, fieldAreaMatrix, minArea) # addZoneToRawMatixIfNone(redZoneRawMatrix, leftZoneNo, fieldAreaMatrix, minArea) redZoneMatrix[leftZoneNo]["total"] += redCount["left"] redZoneMatrix[leftZoneNo]["right"] += redCount["left"] rightZoneNo = getAdjecentZoneNo( zoneNo, False, fieldAreaMatrix, minArea) # addZoneToRawMatixIfNone(redZoneRawMatrix, rightZoneNo, fieldAreaMatrix, minArea) 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] zones = [1, 2, 3, 4, 5, 6, 7, 8, 9] 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)] redPixels2 = [(13, 13, 13, 255), (191, 191, 191, 255), (219, 219, 219, 255), (235, 235, 235, 255), (254, 250, 202, 255), (238, 232, 182, 255), (222, 218, 157, 255), (205, 200, 132, 255), (191, 183, 108, 255), (175, 195, 98, 255), (164, 205, 87, 255)] # elseif ind_i>0 && ind_i <= 0.025 # c_map2(i,1) = 254; # c_map2(i,2) = 250; # c_map2(i,3) = 202; # elseif ind_i>0.025 && ind_i <= 0.05 # c_map2(i,1) = 238; # c_map2(i,2) = 232; # c_map2(i,3) = 182; # elseif ind_i>0.05 && ind_i <= 0.075 # c_map2(i,1) = 222; # c_map2(i,2) = 218; # c_map2(i,3) = 157; # elseif ind_i>0.075 && ind_i <= 0.1 # c_map2(i,1) = 205; # c_map2(i,2) = 200; # c_map2(i,3) = 132; # elseif ind_i>0.1 && ind_i <= 0.125 # c_map2(i,1) = 191; # c_map2(i,2) = 183; # c_map2(i,3) = 108; # elseif ind_i>0.125 && ind_i <= 0.15 # c_map2(i,1) = 175; # c_map2(i,2) = 195; # c_map2(i,3) = 98; # elseif ind_i>0.15 && ind_i <= 0.175 # c_map2(i,1) = 164; # c_map2(i,2) = 205; # c_map2(i,3) = 87; # elseif ind_i>0.175 && ind_i <= 0.2 # c_map2(i,1) = 127; # c_map2(i,2) = 179; # c_map2(i,3) = 71; # elseif ind_i>0.2 && ind_i <= 0.25 # c_map2(i,1) = 111; # c_map2(i,2) = 161; # c_map2(i,3) = 64; def findIfRedZonePixel(pixelData, isCmap2): return checkIfColorInList(pixelData, (redPixels if not isCmap2 else redPixels2)) for redPixelData in (redPixels if not isCmap2 else redPixels2): if abs(sum(redPixelData)-sum(pixelData)) < 10: return True return False def checkIfColorInList(color, list): for pixelData in list: if abs(sum(pixelData)-sum(color)) < 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 getFullDirByCode(code): if code == "N": return "north" if code == "W": return "west" if code == "E": return "east" if code == "C": return "ceNter" if code == "S": return "south" r2lLangs = ["ar"] def getLocalDirByZone(zone, translations, langCode): if zone == 1: if langCode in r2lLangs: return translations[getFullDirByCode("W")]+"\n"+translations[getFullDirByCode("N")] return translations[getFullDirByCode("N")]+"\n"+translations[getFullDirByCode("W")] if zone == 2: return translations[getFullDirByCode("N")] if zone == 3: if langCode in r2lLangs: return translations[getFullDirByCode("E")]+"\n"+translations[getFullDirByCode("N")] return translations[getFullDirByCode("N")]+"\n"+translations[getFullDirByCode("E")] if zone == 4: return translations[getFullDirByCode("W")] if zone == 5: return translations[getFullDirByCode("C")] if zone == 6: return translations[getFullDirByCode("E")] if zone == 7: if langCode in r2lLangs: return translations[getFullDirByCode("W")]+"\n"+translations[getFullDirByCode("S")] return translations[getFullDirByCode("S")]+"\n"+translations[getFullDirByCode("W")] if zone == 8: return translations[getFullDirByCode("S")] if zone == 9: if langCode in r2lLangs: return translations[getFullDirByCode("E")]+"\n"+translations[getFullDirByCode("S")] return translations[getFullDirByCode("S")]+"\n"+translations[getFullDirByCode("E")] def getSmsInstructionsByZones(redZones, translations, langCode): def getLocalDir(zone): return getLocalDirByZone(zone, translations, langCode) result = ", ".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 = "report_images/field_img8.png" #"sampleField.png" # redZones = getRedZones(imgPath, True) # 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="report_images/dirImg.png", translations=None, langCode=None): 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 def getLocalName(zone): # langCode is only expected as hi return getLocalDirByZone(zone, translations, langCode) if translations != None: zoneNames = list(map(getLocalName, zones)) else: zoneNames = list(map(zoneToStr, zones)) fontSize = 26 if translations != None else 50 if langCode == "bn": fontPath = "report_fonts/Hind_Siliguri/HindSiliguri-Light.ttf" elif langCode == "te": fontPath = "report_fonts/Noto_Sans_Telugu/static/NotoSansTelugu/NotoSansTelugu-Light.ttf" elif langCode == "ta": fontPath = "report_fonts/Noto_Sans_Tamil/static/NotoSansTamil/NotoSansTamil-Light.ttf" elif langCode == "kn": fontPath = "report_fonts/Noto_Sans_Kannada/static/NotoSansKannada/NotoSansKannada-Light.ttf" # elif langCode=="hi": # fontPath = "report_fonts/Mukta/Mukta-Light.ttf" else: fontPath = "report_fonts/Noto_Sans/NotoSans-Bold.ttf" font = ImageFont.truetype(fontPath, fontSize) widthF = round((width1-80)/2) heightF = round((height1-100)/2) # print(zoneNames) for zone in zones: dirOffset = getDirOffsetByZone( zone, width1, width2, widthF, height1, height2, heightF) index = zone-1 zoneName = zoneNames[index] editableImg.text(dirOffset, zoneName, (255, 50, 36), font) # 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) def getDirOffsetByZone(zone, width1, width2, widthF, height1, height2, heightF): if zone == 1: return (widthF, heightF) if zone == 2: return (width1+widthF, heightF) if zone == 3: return (width2+widthF, heightF) if zone == 4: return (widthF, height1+heightF) if zone == 5: return (width1+widthF, height1+heightF) if zone == 6: return (width2+widthF, height1+heightF) if zone == 7: return (widthF, height2+heightF) if zone == 8: return (width1+widthF, height2+heightF) if zone == 9: return (width2+widthF, height2+heightF) # tranlations = { # "north": "उत्तर", # "east": "पूर्व", # "west": "पश्चिम", # "south": "दक्षिण", # "ceNter": "केंद्र" # } # imgToMask = "report_images/field_img7.png" # # createFieldDirImg(imgToMask) # createFieldDirImg(imgToMask, "report_images/dirImghi.png", tranlations, "hi") # print("done") cloudyPixels = [(255, 255, 0, 255), (0, 0, 0, 255), (255, 255, 255, 255)] def isCloudyImg(etciPath): img = Image.open(etciPath) pixelValues = list(img.getdata()) colors = img.getcolors() print("colors: ", colors) print("totalPixels: ", len(pixelValues)) # print("pixels", pixelValues) # return 0 imgSize = img.size # w-h print("imgSize: ", imgSize) imgWidth = imgSize[0] imgHeight = imgSize[1] fieldPixels = 0 cloudyPixelsNo = 0 for x in range(imgWidth): for y in range(imgHeight): pixelData = pixelValues[y*imgWidth+x] if pixelData[3] == 255: fieldPixels += 1 if checkIfColorInList(pixelData, cloudyPixels): cloudyPixelsNo += 1 print("cloudyPixels", cloudyPixelsNo) print("fieldPixels", fieldPixels) return cloudyPixelsNo > fieldPixels*0.3 # etciPath = "report_images/field_img8_etci.png" # print(isCloudyImg(etciPath)) def createDirOnMapImg(dirImgPath, mapImgPath, mapDimens, outPath): dirImg = Image.open(dirImgPath, "r") mapImg = Image.open(mapImgPath) horiPadPer = mapDimens[2] verPadPer = mapDimens[3] horiPad = (mapDimens[0]*horiPadPer)/(1+2*horiPadPer) # in pixels verPad = (mapDimens[1]*verPadPer)/(1+2*verPadPer) # in pixels width = mapDimens[0]/(1+2*horiPadPer) # height = mapDimens[1]/(1+2*verPadPer) magnifyRatio = dirImg.size[0]/width # print(width, height, horiPad, verPad) # resizedDirImg = dirImg.resize((round(width), round(height)), Image.LANCZOS) # resizedDirImg.save("report_images/resizeDirImg.png") # , round(horiPad+width), round(verPad+height) resizedMapImg = mapImg.resize((round(magnifyRatio*mapImg.size[0]), round(magnifyRatio*mapImg.size[1])), Image.LANCZOS) resizedMapImg.paste(dirImg, (round(magnifyRatio*horiPad), round(magnifyRatio*verPad)), mask=dirImg) resizedMapImg.save(outPath) # dirImgPath="report_images/dirImghi.png" # mapImgPath="report_images/fieldMap.jpg" # dimens=(167.91809200993967, 335.83618401987934, # 0.5328091778105274, 0.09999999999999996) # # 44.64947605769587 153.71462885606567 # # aspect: 0.2904699207224087 # # new w-h: 76.85731442803284 153.71462885606567 # # len 184.4575546272788 # # 167.91809200993967 335.83618401987934 18 0.5492486021588433 0.1 0.1 # # 92.2287758, 184.46091 (37.845, 15.373)/ # # (167.91809200993967, 335.83618401987934, 0.5328091778105274, 0.09999999999999996) # outPath="report_images/dirMapImg.png" # createDirOnMapImg(dirImgPath, mapImgPath, dimens, outPath)