def brightness(im): stat = ImageStat.Stat(im) r, g, b = stat.mean #return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) #this is a way of averaging the r g b values to derive "human-visible" brightness return math.sqrt(0.577 * (r**2) + 0.577 * (g**2) + 0.577 * (b**2))
def psnr(img1, img2): diff_img = ImageChops.difference(img1, img2) stat = ImageStat.Stat(diff_img) mse = sum(stat.sum2) / len(stat.count) / stat.count[0] return 10 * math.log10(255**2 / mse)
def get_brightness( im_file ): im = Image.open(im_file) im.convert('L') stat = ImageStat.Stat(im) return stat.mean[0]
def get_brightness(image): stat = ImageStat.Stat(image) return stat.rms[0]
def brightness(img): img_b = Image.fromarray(img) stat = ImageStat.Stat(img_b) bright_lvl = stat.mean[0] return bright_lvl
from PIL import Image, ImageStat import picamera import requests import time colorFlag=False; blackFlag=False; while True : with picamera.PiCamera() as camera: camera.resolution = (1280,720) camera.capture("/home/pi/Pic.jpg") im = Image.open("Pic.jpg").convert("RGB") stat = ImageStat.Stat(im) if sum(stat.sum)/3 != stat.sum[0] : if colorFlag==False and blackFlag==False : colorFlag=True else: if colorFlag==False and blackFlag==True : colorFlag==True blackFlag==True else : if sum(stat.sum)/3 == stat.sum[0] : if colorFlag==False and blackFlag==False: blackFlag==True else: if colorFlag==True and blackFlag==False: URL = "http://192.168.1.3:5000/" files = {'image':open('/home/pi/light.jpg')} r=requests.post(URL, files=files) print(r.text) time.sleep(2)
return False draw = ImageDraw.Draw(source) start = time.time() for y in range(sy - ty): # 소스의 처음부터 타겟 사이즈를 뺀 위치 까지 전체 검색을 시작 한다. for x in range( 0, sx - tx, step): # 처음 (10 X 10)개 픽셀의 값이 비슷 하다면 Search()로 타겟 사이즈 전체를 다시 확인한다. compare = source.crop((x, y, x + 10, y + 10)) partial_target = target.crop((0, 0, 10, 10)) diff = ImageChops.difference(compare, partial_target) # 각 픽셀값 차의 절대값이 반환 된다. # Returns the absolute value of the pixel-by-pixel difference between the two images. stat = ImageStat.Stat(diff) if max(max(stat.extrema[0]), max(stat.extrema[1]), max( stat.extrema[2])) < tolerance: if Search(x, y, tolerance) == True: print("Top left point: (%d, %d)" % (x, y)) print("Center of targe point: (%d, %d)" % (x + target.width / 2, y + target.height / 2)) print("Number of total wrong detection: ", trial) draw.rectangle((x, y, x + target.width, y + target.height), outline=(255, 0, 0)) # Draws a rectangle. 소스 이미지의 타겟 부분에 빨간 사각형을 그린다. end = time.time() print("Seraching time: ", end - start) source.show() sys.exit()
def halftone(self, im, cmyk, sample, scale, angles, antialias): """ Returns list of half-tone images for cmyk image. sample (pixels), determines the sample box size from the original image. The maximum output dot diameter is given by sample * scale (which is also the number of possible dot sizes). So sample=1 will presevere the original image resolution, but scale must be >1 to allow variation in dot size. """ # If we're antialiasing, we'll multiply the size of the image by this # scale while drawing, and then scale it back down again afterwards. # Because drawing isn't aliased, so drawing big and scaling back down # is the only way to get antialiasing from PIL/Pillow. antialias_scale = 4 if antialias is True: scale = scale * antialias_scale cmyk = cmyk.split() dots = [] for channel, angle in zip(cmyk, angles): channel = channel.rotate(angle, expand=1) size = channel.size[0] * scale, channel.size[1] * scale half_tone = Image.new("L", size) draw = ImageDraw.Draw(half_tone) # Cycle through one sample point at a time, drawing a circle for # each one: for x in range(0, channel.size[0], sample): for y in range(0, channel.size[1], sample): # Area we sample to get the level: box = channel.crop((x, y, x + sample, y + sample)) # The average level for that box (0-255): mean = ImageStat.Stat(box).mean[0] # The diameter of the circle to draw based on the mean (0-1): diameter = (mean / 255)**0.5 # Size of the box we'll draw the circle in: box_size = sample * scale # Diameter of circle we'll draw: # If sample=10 and scale=1 then this is (0-10) draw_diameter = diameter * box_size # Position of top-left of box we'll draw the circle in: # x_pos, y_pos = (x * scale), (y * scale) box_x, box_y = (x * scale), (y * scale) # Positioned of top-left and bottom-right of circle: # A maximum-sized circle will have its edges at the edges # of the draw box. x1 = box_x + ((box_size - draw_diameter) / 2) y1 = box_y + ((box_size - draw_diameter) / 2) x2 = x1 + draw_diameter y2 = y1 + draw_diameter draw.ellipse([(x1, y1), (x2, y2)], fill=255) half_tone = half_tone.rotate(-angle, expand=1) width_half, height_half = half_tone.size # Top-left and bottom-right of the image to crop to: xx1 = (width_half - im.size[0] * scale) / 2 yy1 = (height_half - im.size[1] * scale) / 2 xx2 = xx1 + im.size[0] * scale yy2 = yy1 + im.size[1] * scale half_tone = half_tone.crop((xx1, yy1, xx2, yy2)) if antialias is True: # Scale it back down to antialias the image. w = (xx2 - xx1) / antialias_scale h = (yy2 - yy1) / antialias_scale half_tone = half_tone.resize((w, h), resample=Image.LANCZOS) dots.append(half_tone) return dots
def main(): # assign state to mouse button clicks state_left = win32api.GetKeyState( 0x01) # Left button down = 0 or 1. Button up = -127 or -128 state_right = win32api.GetKeyState( 0x02) # Right button down = 0 or 1. Button up = -127 or -128 # initialize size of matrix cells = 8 # adjust darkness to screenshot for color calibration darkness = .18 # initialize matrices Matrix = [[0 for i in range(cells)] for j in range(cells)] # user #comment out after readme file created #### print("left click at top left corner of jewel field, hold, and release at bottom right corner of jewel field") # loop for setting area of matrix while True: a = win32api.GetKeyState(0x01) b = win32api.GetKeyState(0x02) if a != state_left: # Button state changed state_left = a if a < 0: x1, y1 = win32api.GetCursorPos() else: x2, y2 = win32api.GetCursorPos() w = x2 - x1 h = y2 - y1 cellWidth = w / cells cellHeight = h / cells break time.sleep(0.01) while True: visualMatrix = [[0 for i in range(cells)] for j in range(cells)] # screenshot board im = pyautogui.screenshot(region=(x1, y1, w, h)) # darken image by 10% im = im.point(lambda x: x * (1 - darkness)) # get median rgb value of part of each cell for i in range(cells): for j in range(cells): box = (i * cellWidth + (cellWidth * (2 / 7)), j * cellHeight + (cellHeight * (2 / 7)), i * cellWidth + cellWidth - (cellWidth * (2 / 7)), j * cellHeight + cellHeight - (cellHeight * (2 / 7))) region = im.crop(box) Matrix[j][i] = ImageStat.Stat(region).median # convert median rgb to primary color rgb or char representation for i in range(cells): for j in range(cells): visualMatrix[j][i] = convert_to_primary(Matrix[j][i]) ## break ## Debug breaker t = Tree(visualMatrix) t.children = [] t = createTree(visualMatrix, cells, t) t.setList() t.children.sort() ## break ## Debug breaker # click away counter = 0 for child in t.children: if counter > 4: break clck1 = child.c1 clck2 = child.c2 pyautogui.moveTo(x1 + int(clck1[1] * cellWidth + cellWidth / 2), y1 + int(clck1[0] * cellHeight + cellHeight / 2)) time.sleep(.01) pyautogui.click() pyautogui.moveTo(x1 + int(clck2[1] * cellWidth + cellWidth / 2), y1 + int(clck2[0] * cellHeight + cellHeight / 2)) time.sleep(.01) pyautogui.click() counter += 1
def contrast(im_file): stat = ImageStat.Stat(im2) return stat.rms[0]
def WriteMeterics(image, classID, data_filename): if len(image.getbands()) == 3: #write class data to file f_handle = open(data_filename, 'a') f_handle.write(str(classID)) f_handle.write(', ') f_handle.close() #calculate LBP histogram on raw image np_img = np.array(image) lbp1 = mahotas.features.lbp(np_img, 1, 8, ignore_zeros=False) #print lbp1.ndim, lbp1.size print "LBP Histogram: ", lbp1 print "LBP Length:", len(lbp1) f_handle = open(data_filename, 'a') for i in range(len(lbp1)): f_handle.write(str(lbp1[i])) f_handle.write(" ") f_handle.write(',') f_handle.close() print "Image has multiple color bands...Splitting Bands...." Red_Band, Green_Band, Blue_Band = image.split() print "Calculating Histogram for I3 pixels of image..." I3_Histogram = CalcHistogram(Green_Band) #gaussian_numbers = normal(size=1000) plt.hist(I3_Histogram, bins=32) plt.title("I3 Histogram") plt.xlabel("Value") plt.ylabel("Frequency") #plt.show(block=False) plt.savefig("out.png") plt.clf() cv_image = cv.LoadImage("out.png") cv.ShowImage("I3 Histogram", cv_image) cv.MoveWindow ('I3 Histogram',705 ,50 ) time.sleep(.1) cv.WaitKey(100) #p = Process(target=plot_graph, args=([I3_Histogram],)) #p.start() #p.join() #save I3 Histogram to file in certain format print "saving I3 histogram to dictionary..." f_handle = open(data_filename, 'a') for i in range(len(I3_Histogram)): f_handle.write(str(I3_Histogram[i])) f_handle.write(" ") f_handle.write(',') f_handle.close() #calculate RGB histogram on raw image rgb_histo = image.histogram() print "saving RGB histogram to dictionary..." f_handle = open(data_filename, 'a') for i in range(len(rgb_histo)): f_handle.write(str(rgb_histo[i])) f_handle.write(" ") f_handle.write(',') f_handle.close() #calculate I3 meterics I3_sum = ImageStat.Stat(image).sum I3_sum2 = ImageStat.Stat(image).sum2 I3_median = ImageStat.Stat(image).median I3_mean = ImageStat.Stat(image).mean I3_var = ImageStat.Stat(image).var I3_stddev = ImageStat.Stat(image).stddev I3_rms = ImageStat.Stat(image).rms print "saving I3 meterics to dictionary..." f_handle = open(data_filename, 'a') print "sum img1_I3: ", I3_sum[1] print "sum2 img1_I3: ", I3_sum2[1] print "median img1_I3: ", I3_median[1] print "avg img1_I3: ", I3_mean[1] print "var img1_I3: ", I3_var[1] print "stddev img1_I3: ", I3_stddev[1] print "rms img1_I3: ", I3_rms[1] #print "extrema img1_I3: ", ImageStat.Stat(img1_I3).extrema #print "histogram I3: ", len(img1_I3.histogram()) f_handle.write(str(I3_sum[1])) f_handle.write(",") f_handle.write(str(I3_sum2[1])) f_handle.write(",") f_handle.write(str(I3_median[1])) f_handle.write(",") f_handle.write(str(I3_mean[1])) f_handle.write(",") f_handle.write(str(I3_var[1])) f_handle.write(",") f_handle.write(str(I3_stddev[1])) f_handle.write(",") f_handle.write(str(I3_rms[1])) #f_handle.write(",") f_handle.write('\n') f_handle.close() else: print "image not valid for processing: ", filename1 time.sleep(5) return
def brightness(im_file): stat = ImageStat.Stat(im2) return stat.mean[0]
def transform_cords(self, image, bbox, segmentation_in_original_image): mean_template_and_detection = tuple( map(round, ImageStat.Stat(image).mean)) bbox_xywh = np.array( [bbox[0] + bbox[2] // 2, bbox[1] + bbox[3] // 2, bbox[2], bbox[3]], np.float32) # 将标注ann中的bbox从左上点的坐标+bbox长宽 -> 中心点的坐标+bbox的长宽 bbox_x1y1x2y2 = np.array( [bbox[0], bbox[1], bbox[0] + bbox[2], bbox[1] + bbox[3]], np.float32) # 将标注ann中的bbox从左上点的坐标+bbox长宽 -> 左上点的坐标+右下点的坐标 original_image_w, original_image_h = image.size cx, cy, tw, th = bbox_xywh p = round((tw + th) / 2, 2) template_square_size = int(np.sqrt((tw + p) * (th + p))) # a detection_square_size = int(template_square_size * 2) # A = 2a # pad detection_lt_x, detection_lt_y = cx - detection_square_size // 2, cy - detection_square_size // 2 detection_rb_x, detection_rb_y = cx + detection_square_size // 2, cy + detection_square_size // 2 left = -detection_lt_x if detection_lt_x < 0 else 0 top = -detection_lt_y if detection_lt_y < 0 else 0 right = detection_rb_x - original_image_w if detection_rb_x > original_image_w else 0 bottom = detection_rb_y - original_image_h if detection_rb_y > original_image_h else 0 padding = tuple(map(int, [left, top, right, bottom])) padding_image_w, padding_image_h = left + right + original_image_w, top + bottom + original_image_h template_img_padding = ImageOps.expand( image, border=padding, fill=mean_template_and_detection) detection_img_padding = ImageOps.expand( image, border=padding, fill=mean_template_and_detection) # crop tl = cx + left - template_square_size // 2 tt = cy + top - template_square_size // 2 tr = padding_image_w - tl - template_square_size tb = padding_image_h - tt - template_square_size template_img_crop = ImageOps.crop(template_img_padding.copy(), (tl, tt, tr, tb)) dl = np.clip(cx + left - detection_square_size // 2, 0, padding_image_w - detection_square_size) dt = np.clip(cy + top - detection_square_size // 2, 0, padding_image_h - detection_square_size) dr = np.clip(padding_image_w - dl - detection_square_size, 0, padding_image_w - detection_square_size) db = np.clip(padding_image_h - dt - detection_square_size, 0, padding_image_h - detection_square_size) detection_img_crop = ImageOps.crop(detection_img_padding.copy(), (dl, dt, dr, db)) detection_tlcords_of_original_image = (cx - detection_square_size // 2, cy - detection_square_size // 2) detection_rbcords_of_original_image = (cx + detection_square_size // 2, cy + detection_square_size // 2) detection_tlcords_of_padding_image = (cx - detection_square_size // 2 + left, cy - detection_square_size // 2 + top) detection_rbcords_of_padding_image = (cx + detection_square_size // 2 + left, cy + detection_square_size // 2 + top) # resize template_img_resized = template_img_crop.copy().resize((127, 127)) detection_img_resized = detection_img_crop.copy().resize((256, 256)) template_resized_ratio = round(127 / template_square_size, 2) detection_resized_ratio = round(256 / detection_square_size, 2) segmentation_in_padding_img = segmentation_in_original_image for i in range(len(segmentation_in_original_image)): for j in range(len(segmentation_in_original_image[i]) // 2): segmentation_in_padding_img[i][ 2 * j] = segmentation_in_original_image[i][2 * j] + left segmentation_in_padding_img[i][ 2 * j + 1] = segmentation_in_original_image[i][2 * j + 1] + top x11, y11 = detection_tlcords_of_padding_image x12, y12 = detection_rbcords_of_padding_image segmentation_in_cropped_img = segmentation_in_padding_img for i in range(len(segmentation_in_padding_img)): for j in range(len(segmentation_in_padding_img[i]) // 2): segmentation_in_cropped_img[i][ 2 * j] = segmentation_in_padding_img[i][2 * j] - x11 segmentation_in_cropped_img[i][ 2 * j + 1] = segmentation_in_padding_img[i][2 * j + 1] - y11 segmentation_in_cropped_img[i][2 * j] = np.clip( segmentation_in_cropped_img[i][2 * j], 0, x12 - x11).astype(np.float32) segmentation_in_cropped_img[i][2 * j + 1] = np.clip( segmentation_in_cropped_img[i][2 * j + 1], 0, y12 - y11).astype(np.float32) segmentation_in_detection = segmentation_in_cropped_img for i in range(len(segmentation_in_cropped_img)): for j in range(len(segmentation_in_cropped_img[i])): segmentation_in_detection[i][j] = segmentation_in_cropped_img[ i][j] * detection_resized_ratio blcords_of_bbox_in_padding_image, btcords_of_bbox_in_padding_image, brcords_of_bbox_in_padding_image, bbcords_of_bbox_in_padding_image = \ bbox_x1y1x2y2[0] + left, bbox_x1y1x2y2[1] + top, bbox_x1y1x2y2[2] + left, bbox_x1y1x2y2[3] + top blcords_of_bbox_in_detection, btcords_of_bbox_in_detection, brcords_of_bbox_in_detection, bbcords_of_bbox_in_detection = blcords_of_bbox_in_padding_image - x11, btcords_of_bbox_in_padding_image - y11, brcords_of_bbox_in_padding_image - x11, bbcords_of_bbox_in_padding_image - y11 x1 = np.clip(blcords_of_bbox_in_detection, 0, x12 - x11).astype(np.float32) y1 = np.clip(btcords_of_bbox_in_detection, 0, y12 - y11).astype(np.float32) x2 = np.clip(brcords_of_bbox_in_detection, 0, x12 - x11).astype(np.float32) y2 = np.clip(bbcords_of_bbox_in_detection, 0, y12 - y11).astype(np.float32) cords_of_bbox_in_cropped_detection = np.array([x1, y1, x2, y2], dtype=np.float32) cords_of_bbox_in_resized_detection = cords_of_bbox_in_cropped_detection * detection_resized_ratio return (template_img_resized, detection_img_resized, cords_of_bbox_in_resized_detection, segmentation_in_detection)
data = [[ 'filename', 'desc', 'id', 'width', 'height', 'mean', 'median', 'x_max', 'y_max' ]] for filename in listdir('../../images'): if filename == '.DS_Store': continue path = '../../images/' + filename desc = ' '.join(filename[12:].split('-')[:-1]) idd = filename.split('-')[-1][:-4] image = Image.open(path) width, height = image.size mean = ImageStat.Stat(image).mean mean = tuple([int(x) for x in mean]) image_greyscale = Image.open(path).convert('LA') median = ImageStat.Stat(image_greyscale).median[0] pixels = image.getdata() minimum = 1000000000000 x_max = 0 # poziomo y_max = 0 # pionowo for i, pixel in enumerate(pixels): if pixel == (255, 255, 255): x = i % width y = i // width norma = sqrt(x**2 + y**2) if norma < minimum: minimum = norma
def viz_drc(self, im): '''Like above except try to do DRC to filter out false positives''' print 'viz()' means = {'r': [], 'g': [], 'b': [], 'u': []} threshm = {} c2x = {} r2y = {} r = 0 for y in drange(0, im.size[1], self.gridp): y = int(y) r2y[r] = y c = 0 for x in drange(0, im.size[0], self.gridp): x = int(x) c2x[c] = x # TODO: look into using mask # I suspect this is faster imxy = im.crop( (x, y, x + int(self.gridp), y + int(self.gridp))) mean = ImageStat.Stat(imxy).mean mmean = sum(mean[0:3]) / 3.0 means['r'].append(mean[0]) means['g'].append(mean[1]) means['b'].append(mean[2]) means['u'].append(mmean) #print 'x%0.4d y%0.4d: % 8.3f % 8.3f % 8.3f % 8.3f % 8.3f' % (x, y, mean[0], mean[1], mean[2], mean[3], mmean) threshm[(c, r)] = mmean c += 1 r += 1 cols = c rows = r print 'Design grid: %dc x %dr' % (cols, rows) def rowcol(): for c in xrange(cols): for r in xrange(rows): yield (c, r) viz = im.copy() draw = ImageDraw.Draw(viz) def bitmap_save(bitmap, fn): bitmap2fill = { 'v': 'black', 'm': 'blue', 'u': 'orange', } for c, r in rowcol(): fill = bitmap2fill[bitmap[(c, r)]] x = c2x[c] y = r2y[r] draw.rectangle( (x, y, x + int(self.gridp), y + int(self.gridp)), fill=fill) viz.save(fn) print def gen_bitmap(threshl, threshh): ''' m: metal v: void / nothing u: unknown ''' bitmap = {} print 'Generating bitmap' # looks ugly due to non-integer pitch + randomized order #for (c, r), thresh in threshm.iteritems(): unk_open = set() for c, r in rowcol(): thresh = threshm[(c, r)] x = c2x[c] y = r2y[r] # The void if thresh <= threshl: bitmap[(c, r)] = 'v' # Pretty metal elif thresh >= threshh: bitmap[(c, r)] = 'm' # WTFBBQ else: bitmap[(c, r)] = 'u' unk_open.add((c, r)) return (bitmap, unk_open) (bitmap, unk_open) = gen_bitmap(self.threshl, self.threshh) print 'Unknown (initial): %d' % len(unk_open) bitmap_save(bitmap, os.path.join(self.outdir, 'viz_drc_01_init.png')) print ''' If an unknown is surrounded by void eliminate it Its very likely noise ''' print 'Looking for lone unknowns' def filt_unk_lone(bitmap, unk_open): for c, r in set(unk_open): # look for adjacent if (bitmap.get((c - 1, r), 'v') == 'v' and bitmap.get( (c + 1, r), 'v') == 'v' and bitmap.get( (c, r - 1), 'v') == 'v' and bitmap.get( (c, r + 1), 'v') == 'v'): print ' Unknown %dc, %dr rm: lone' % (c, r) bitmap[(c, r)] = 'v' unk_open.discard((c, r)) filt_unk_lone(bitmap, unk_open) print 'Unknown (post-lone): %d' % len(unk_open) bitmap_save(bitmap, os.path.join(self.outdir, 'viz_drc_02_lone.png')) def has_around(bitmap, c, r, t, d='v'): return (bitmap.get((c - 1, r), d) == t or bitmap.get( (c + 1, r), d) == t or bitmap.get((c, r - 1), d) == t or bitmap.get((c, r + 1), d) == t) print ''' If a single unknown is on a contiguous strip of metal its likely a via has distorted it Note: this will ocassionally cause garbage to incorrectly merge nets ''' def munge_unk_cont(bitmap, unk_open): for c, r in set(unk_open): # Abort if any adjacent unknowns if has_around(bitmap, c, r, 'u'): continue # Is there surrounding metal? if not has_around(bitmap, c, r, 'm'): continue print ' Unknown %dc, %dr => m: join m' % (c, r) bitmap[(c, r)] = 'm' unk_open.discard((c, r)) print 'Looking for lone unknowns' munge_unk_cont(bitmap, unk_open) print 'Unknown (post-cont): %d' % len(unk_open) bitmap_save(bitmap, os.path.join(self.outdir, 'viz_drc_03_cont.png')) print ''' Try to propagate using more aggressive threshold after initial truth is created that we are pretty confident in Any warnings in aggressive adjacent to metal in baseline are taken as truth ''' print 'prop_ag()' def prop_ag(bitmap, bitmap_ag): for c, r in rowcol(): # Skip if nothing is there if bitmap_ag[(c, r)] == 'v': continue # Do we already think something is there? if bitmap[(c, r)] == 'm': continue # Is there something to extend? if not has_around(bitmap, c, r, 'm'): continue print ' %dc, %dr => m: join m' % (c, r) bitmap[(c, r)] = 'm' # above 10 generated false positives # below 9 lost one of the fixes # keep at 9 for now as it stil has some margin bitmap_ag, _unk_open = gen_bitmap(self.threshl - 9, self.threshh) bitmap_save(bitmap_ag, os.path.join(self.outdir, 'viz_drc_04-1_ag.png')) prop_ag(bitmap, bitmap_ag) print 'Unknown (post-ag): %d' % len(unk_open) bitmap_save(bitmap, os.path.join(self.outdir, 'viz_drc_04-2_ag.png')) print print 'Final counts' for c in 'mvu': print ' %s: %d' % (c, len(filter(lambda k: k == c, bitmap.values())))
#color quantization quantized_image = color_quant(face) #plt.imshow(quantized_image) #plt.show() face = Image.fromarray(quantized_image) face_np = face.convert('RGB') face_np = np.array(face_np) face_np = face_np[:, :, ::-1].copy() #splitting colors R = face_and[:, :, 0] l = len(R[np.nonzero(R)]) mean = [int(x/l) for x in ImageStat.Stat(face).sum] #to convert BGR to RGB org_img = image[:, :, ::-1].copy() #draw an ellipse with fill color as the detected skin color out = Image.fromarray(org_img) d = Draw(out) d.ellipse(((0,0),(0.2*image.shape[0],0.2*image.shape[1])), fill = tuple(mean)) success += 1 #out.save('../results/out6/out_file_'+str(success)+'.jpg') print('Success ' + str(success)) plt.imshow(out) plt.show() except: fail += 1 print('Fail ' + str(fail))
def svg_centerline_trace(self, image_file, cliprect=None): """ svg_centerline_trace prepares the image by a) limiting_size (aka runtime), b) removing noise, c) linear histogram expansion, d) equalized spatial illumnination (my own algorithm) Then we run several iterations of autotrace and find the optimal black white threshold by evaluating all outputs. The output with the longest total path and the least path elements wins. A cliprect dict with the keys x, y, w, h can be specified. All 4 are expected in the range 0..1 and are mapped to the image width and height. """ num_attempts = self.candidates # 15 is great. min 1, max 255, beware it gets much slower with more attempts. autotrace_cmd = [ autotrace_exe, '--filter-iterations', str(self.options.at_filter_iterations), '--error-threshold', str(self.options.at_error_threshold), '--centerline', '--input-format=pbm', '--output-format=svg' ] autotrace_cmd += self.autotrace_opts stroke_style_add = 'stroke-width:%.2f; fill:none; stroke-linecap:round;' if debug: print("svg_centerline_trace start " + image_file, file=self.tty) if debug: print('+ ' + ' '.join(autotrace_cmd), file=self.tty) im = Image.open(image_file) orig_im_size = (im.size[0], im.size[1]) box = [0, 0, 0, 0] if cliprect is not None: box[0] = cliprect['x'] * im.size[0] box[1] = cliprect['y'] * im.size[1] # sorted(min, val, max)[1] does clamping without chaining min(max()) in an ugly way. box[2] = sorted((0, int(0.5 + box[0] + cliprect['w'] * im.size[0]), im.size[0]))[1] box[3] = sorted((0, int(0.5 + box[1] + cliprect['h'] * im.size[1]), im.size[1]))[1] box[0] = sorted((0, int(0.5 + box[0]), im.size[0]))[1] box[1] = sorted((0, int(0.5 + box[1]), im.size[1]))[1] im = im.crop(box) if box[0] == box[2] or box[1] == box[3]: print("ERROR: Cliprect and Image do not overlap.", orig_im_size, box, cliprect, file=sys.stderr) return ('<svg/>', 1, orig_im_size) if 'A' in im.mode: # this image has alpha. Paste it onto white or black. im = im.convert("RGBA") if self.invert_image: bg = Image.new('RGBA', im.size, (0, 0, 0, 255)) # black background else: bg = Image.new('RGBA', im.size, (255, 255, 255, 255)) # white background im = Image.alpha_composite(bg, im) im = im.convert(mode='L', dither=None) if debug: print("seen: " + str([im.format, im.size, im.mode]), file=self.tty) scale_limit = math.sqrt(im.size[0] * im.size[1] * 0.000001 / self.megapixel_limit) if scale_limit > 1.0: print("Megapixel limit (" + str(self.megapixel_limit) + ") exceeded. Scaling down by factor : " + str(scale_limit), file=sys.stderr) im = im.resize( (int(im.size[0] / scale_limit), int(im.size[1] / scale_limit)), resample=Image.BILINEAR) if self.invert_image: im = ImageOps.invert(im) ### Add a one pixel padding around the image. Otherwise autotrace fails when a line touches the edge of the image. im = ImageOps.expand(im, border=1, fill=255) if self.filter_median > 0: if self.filter_median % 2 == 0: self.filter_median = self.filter_median + 1 # need odd values. im = im.filter(ImageFilter.MedianFilter(size=self.filter_median) ) # feeble denoise attempt. FIXME: try ROF instead. im = ImageOps.autocontrast( im, cutoff=0) # linear expand histogram (an alternative to equalize) ## cutoff=2 destroys some images, see https://github.com/fablabnbg/inkscape-centerline-trace/issues/28 # not needed here: # im = im.filter(ImageFilter.UnsharpMask(radius=2, percent=150, threshold=3)) # parameters depend on size of image! if self.filter_equal_light > 0.0: scale_thumb = math.sqrt(im.size[0] * im.size[1] * 0.0001) # exactly 0.01 MP (e.g. 100x100) im_neg_thumb = ImageOps.invert( im.resize((int( im.size[0] / scale_thumb), int(im.size[1] / scale_thumb)), resample=Image.BILINEAR)) im_neg_thumb = im_neg_thumb.filter( ImageFilter.GaussianBlur(radius=30)) im_neg_blur = im_neg_thumb.resize(im.size, resample=Image.BILINEAR) if self.options.debug: im_neg_blur.show() if debug: print("ImageOps.equalize(im) done", file=self.tty) im = Image.blend(im, im_neg_blur, self.filter_equal_light * 0.5) im = ImageOps.autocontrast( im, cutoff=0 ) # linear expand histogram (an alternative to equalize) if self.options.debug: im.show() def svg_pathstats(path_d): """ calculate statistics from an svg path: length (measuring bezier splines as straight lines through the handles). points (all, including duplicates) segments (number of not-connected!) path segments. """ path_d = path_d.lower() p_points = 0 p_length = 0 p_segments = 0 for p in path_d.split('m'): pp = re.sub('[cl,]', ' ', p) pp, closed = re.subn('z\s*$', '', pp) xy = pp.split() if len(xy) < 2: # print len(pp) # print "short path error" continue x0 = float(xy[0]) y0 = float(xy[1]) p_points += 1 x = xy[2::2] y = xy[3::2] if len(x): p_segments += 1 if closed: x.extend(x0) y.extend(y0) for i in range(len(x)): p_points += 1 dx = float(x[i]) - x0 dy = float(y[i]) - y0 p_length += math.sqrt(dx * dx + dy * dy) x0, y0 = float(x[i]), float(y[i]) return { 'points': p_points, 'segments': p_segments, 'length': p_length } # slice with a list of histogram maps # 1 -> 128 # 3 -> 64,128,192 # ... candidate = {} if self.options.debug: im.show() for i in range(num_attempts): threshold = int(256. * (1 + i) / (num_attempts + 1)) lut = [255 for n in range(threshold) ] + [0 for n in range(threshold, 256)] if debug: print("attempt " + str(i), file=self.tty) bw = im.point(lut, mode='1') if debug: print("bw from lut done: threshold=%d" % threshold, file=self.tty) if self.options.debug: bw.show(command="/usr/bin/display -title=bw:threshold=%d" % threshold) cand = { 'threshold': threshold, 'img_width': bw.size[0], 'img_height': bw.size[1], 'mean': ImageStat.Stat(im).mean[0] } fp = tempfile.NamedTemporaryFile(prefix="centerlinetrace", suffix='.pbm', delete=False) fp.write(b"P4\n%d %d\n" % (bw.size[0], bw.size[1])) fp.write(bw.tobytes()) fp.close() if debug: print("pbm from bw done", file=self.tty) # try: p = subprocess.Popen(autotrace_cmd + [fp.name], stdout=subprocess.PIPE) # the following crashes Inkscape (!) when used with GUI and autotrace not installed #except Exception as e: #print '+ '+' '.join(autotrace_cmd) #print e #print "Try:\n sudo apt-get install autotrace" #sys.exit(1) cand['svg'] = p.communicate()[0] if debug: print("autotrace done", file=self.tty) if not len(cand['svg']): print("autotrace_cmd: " + ' '.join(autotrace_cmd + [fp.name]), file=sys.stderr) print( "ERROR: returned nothing, leaving tmp bmp file around for you to debug", file=sys.stderr) cand['svg'] = '<svg/>' # empty dummy else: os.unlink(fp.name) # <?xml version="1.0" standalone="yes"?>\n<svg width="86" height="83">\n<path style="stroke:#000000; fill:none;" d="M36 15C37.9219 18.1496 41.7926 19.6686 43.2585 23.1042C47.9556 34.1128 39.524 32.0995 35.179 37.6034C32.6296 40.8328 34 48.1105 34 52M36 17C32.075 22.4565 31.8375 30.074 35 36M74 42L46 38C45.9991 46.1415 46.7299 56.0825 45.6319 64C44.1349 74.7955 23.7094 77.5566 16.044 72.3966C7.27363 66.4928 8.04426 45.0047 16.2276 38.7384C20.6362 35.3626 27.7809 36.0006 33 36M44 37L45 37"/>\n</svg> try: xml = etree.fromstring(cand['svg']) except: print("autotrace_cmd: " + ' '.join(autotrace_cmd + [fp.name]), file=sys.stderr) print("ERROR: no proper xml returned: '" + cand['svg'] + "'", file=sys.stderr) xml = etree.fromstring('<svg/>') # empty dummy p_len, p_seg, p_pts = 0, 0, 0 for p in xml.findall('path'): pstat = svg_pathstats(p.attrib['d']) p_len += pstat['length'] p_seg += pstat['segments'] p_pts += pstat['points'] cand['length'] = p_len cand['segments'] = p_seg cand['points'] = p_pts if cand['mean'] > 127: cand['mean'] = 255 - cand['mean'] # should not happen blackpixels = cand['img_width'] * cand['img_height'] * cand[ 'mean'] / 255. cand['strokewidth'] = blackpixels / max(cand['length'], 1.0) candidate[i] = cand def calc_weight(cand, idx): offset = (num_attempts / 2. - idx) * (num_attempts / 2. - idx) * ( cand['img_width'] + cand['img_height']) w = cand['length'] * 5 - offset * .005 - cand[ 'points'] * .2 - cand['segments'] * 20 # print "calc_weight(%d) = rl=%f o=%f p=%f s=%f -> w=%f" % (idx, cand['length']*5, offset*.005, cand['points']*.2, cand['segments']*20, w) return w best_weight_idx = 0 for n in candidate.keys(): # print "candidate ", n c = candidate[n] # print "\t mean=%d len=%d seg=%d width=%d" % (c['mean'], c['length'], c['segments'], c['strokewidth']) if calc_weight(c, n) > calc_weight(candidate[best_weight_idx], best_weight_idx): best_weight_idx = n if debug: print("best: %d/%d" % (best_weight_idx, num_attempts), file=self.tty) ## if standalone: # svg = re.sub('stroke:', (stroke_style_add % candidate[best_weight_idx]['strokewidth']) + ' stroke:', candidate[best_weight_idx]['svg']) # return svg ## inkscape-extension: self.tty.close() return (candidate[best_weight_idx]['svg'], candidate[best_weight_idx]['strokewidth'], orig_im_size)
for img_path in picture_names: try: #load image image = cv2.imread(img_path) #make a copy of the image for processing img = image.copy() #face detection detected_faces = detect_faces(img) #crop the detected face img = Image.fromarray(img).crop(detected_faces[0]) #color quantization quantized_image = color_quant(img) face = Image.fromarray(quantized_image) median = ImageStat.Stat(face).median #to convert BGR to RGB org_img = image[:, :, ::-1].copy() #draw an ellipse with fill color as the detected skin color out = Image.fromarray(org_img) d = Draw(out) d.ellipse(((0, 0), (0.2 * image.shape[0], 0.2 * image.shape[1])), fill=tuple(median)) #output the results #plt.imshow(res2) #plt.show() #plt.imshow(out) #plt.axis('off') #plt.show()
def percentImageError(imageA, imageB): stat1 = ImageStat.Stat(imageA) stat2 = ImageStat.Stat(imageB) return math.fabs(stat1.rms[0] - stat2.rms[0])/(stat1.rms[0])
def colorAvg(im, mask): """Takes in a string containing an image file name, returns the average red, blue, and green values for all the pixels in that image.""" imStats = ImageStat.Stat(im, mask) (redAv, greenAv, blueAv) = imStats.mean return redAv, greenAv, blueAv
def is_bright(img_loc): im = Image.open(img_loc.strip()).convert('L') stat = ImageStat.Stat(im) return stat.mean[0] > 200
def process_image(url, gaben_path): """ The core of the application. Takes a URL, returns a processed image. """ # detect face, get x,y response = unirest.get('http://api.skybiometry.com/fc/faces/detect.json' + '?api_key=' + SKYBIO_ID + '&api_secret=' + SKYBIO_SECRET + '&detector=aggressive' + '&attributes=none' + '&urls=' + url) pprint(vars(response)) photos = response.body['photos'] for photo in photos: original = Image.open(cStringIO.StringIO(urllib.urlopen(url).read())) gabenized = original.copy() if not photo['tags']: continue unprocessed = True for face in photo['tags']: # get image values original_roll = face['roll'] original_yaw = face['yaw'] original_center_x = face['center']['x'] original_center_y = face['center']['y'] original_size = face['width'] original_height = photo['height'] original_width = photo['width'] # if yaw is too great, skip MAX_YAW = 30 if abs(original_yaw) > MAX_YAW: continue # hardcoded values for gabenface gaben_roll = -1 gaben_center_x = 51.24 gaben_center_y = 47.53 gaben_size = 67.15 gaben_height = 465 gaben_width = 484 # calculate values for scale and position scale = (original_size * original_width) / (gaben_size * gaben_width) scale_height = gaben_height * scale scale_width = gaben_width * scale place_x = (0.01 * original_center_x * original_width) - (0.01 * gaben_center_x * scale_width) place_y = (0.01 * original_center_y * original_height) - ( 0.01 * gaben_center_y * scale_height) print scale print scale_height print scale_width print place_x print place_y # open image gaben = Image.open(gaben_path) # rotate gaben to match roll gaben = gaben.rotate(int(-1 * original_roll)) # resize gaben gaben = gaben.resize((int(scale_width), int(scale_height))) gabenized.paste(gaben, (int(place_x), int(place_y)), gaben) unprocessed = False if unprocessed: continue # arrange both images final = Image.new("RGB", (original_width, original_height)) final.paste(gabenized, (0, 0)) #final = Image.new("RGB", (original_width * 2, original_height)) #final.paste(original, (0,0)) #final.paste(gabenized, (original_width, 0)) # if original image was grayscale, convert final COLOR_CUTOFF = 100 colors = ImageStat.Stat(original).var if len(colors) == 3 and abs(max(colors) - min(colors)) < COLOR_CUTOFF: final = final.convert('L') return final
def smallifyToMap(): ##Combine the save images into one spritemap and create a font file for name in files: if not os.path.exists(os.path.dirname("out/")): try: os.makedirs(os.path.dirname("out/")) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise with open("out/ArraysForWatch.txt", "w+") as text_file: text_file.write("//Arrays: ") with open("out/fontsToPaste.txt", "w+") as text_file: text_file.write("<fonts>\n") with open("out/constFontArrs.txt", "w+") as text_file: text_file.write("var fontArr = [") with open("out/constJSONArrs.txt", "w+") as text_file: text_file.write("var jsonArr = [") firstRun = True for name in files: pX, pY = 0, 0 fileAng = 0 charOffset = 0 oldpX = 0 oldChar = 0 maxAng = 360 onlyFiles = next(os.walk(name + "ManImage"))[2] ##do this for each image representing a minute/every 6 degrees unless there is one files if len(onlyFiles) > 1: maxAng = 360 else: maxAng = 6 if not firstRun: for filename in ["out/constFontArrs.txt", "out/constJSONArrs.txt"]: with open(filename, 'rb+') as filehandle: filehandle.seek(-1, os.SEEK_END) filehandle.truncate() with open(filename, 'a+') as filehandle: filehandle.write("],") firstRun = False with open("out/constFontArrs.txt", "a+") as text_file: text_file.write("[") with open("out/constJSONArrs.txt", "a+") as text_file: text_file.write("[") for ang in range(0, maxAng, 6): #charOffset += ang/6 currT = ang / 6 if pY >= pIY or (pY == 0 and pX == 0 ) or currT == 30 or currT == 15 or currT == 45: addLineToArrOut(name, currT, ang) if pY >= pIY or ang / 6 == 30 or ang / 6 == 15 or currT == 45: enc_Arr += "]] </jsonData>" with open("out/ArraysForWatch.txt", "a+") as text_file: text_file.write("\n" + enc_Arr) blank_image.save("out/out" + name + str(fileAng) + ".png") blank_image = Image.new("RGB", (pIX, pIY)) blank_text = "info face=out" + name + str( ang ) + " size=50 bold=0 italic=0 charset=ascii unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=0,0 outline=0" blank_text += "\ncommon lineHeight=24 base=24 scaleW=256 scaleH=256 pages=1 packed=0" blank_text += "\npage id=0 file=\"out" + name + str( ang) + ".png\"" blank_text += "\nchars count=255" enc_Arr = "<jsonData id=\"" + name + str(int(currT)) + "\"> [[" #enc_Arr = "const " + name + str(ang) + " = [[" pX, pY, charOffset = 0, 0, 0 fileAng = ang print('working on ' + name + str(fileAng)) im3 = Image.open(name + "ManImage/" + name + str(ang) + ".png") if not (pY == 0 and pX == 0): enc_Arr += "]" imgwidth, imgheight = im3.size for i in range(0, imgwidth, width): for j in range(0, imgheight, height): #box = (240, 240, 240+j,240+i) box = ( j, i, j + height, i + width, ) a = im3.crop(box) t = ImageStat.Stat(a).sum if any(g > 0 for g in t): try: if pX + width > pIX: #pX >= pIX or pX = 0 pY += height blank_image.paste(a, (pX, pY)) #Used to see if there is any weird character skipping or offsetting happening if (pX - width != oldpX and pX != 0): print(name, charOffset + 33, pX, pY) if oldChar + 1 != charOffset: print(name, charOffset + 33, pX, pY, oldChar + 33, oldpX) blank_text += "\nchar id=" + str( int(charOffset + 33) ) + " x=" + str(int(pX)) + " y=" + str( int(pY) ) + " width=24 height=24 xoffset=0 yoffset=0 xadvance=24 page=0 chnl=15" # print(str(int(charOffset + 33)) + " " + str(pX) + " " + str(pY)) # print(bin((int(charOffset + 33) << 20) ^ ((pX) << 10 ) ^ pY)) temp = str(((int(charOffset + 33) << 20) ^ ((j) << 10) ^ i)) if enc_Arr.endswith("["): enc_Arr += temp elif enc_Arr.endswith("]"): enc_Arr += ", [" + temp else: enc_Arr += ", " + temp oldChar = charOffset charOffset += 1 #Watch wont print any character at char 173... so skip it if charOffset + 33 == 173: charOffset += 1 oldpX = pX pX += width with open( "out/fontOut" + name + str(fileAng) + ".fnt", "w") as text_file: text_file.write(blank_text) except Exception as e: print("error") print(e) blank_image.save("out/out" + name + str(fileAng) + ".png") with open("out/ArraysForWatch.txt", "a+") as text_file: text_file.write("\n" + enc_Arr + "]] </jsonData>") # with open("out/constFontArrs.txt", "a+") as text_file: # text_file.write("Rez.Fonts.fnt" + name + str(int(currT)) + "], ") for filename in ["out/constFontArrs.txt", "out/constJSONArrs.txt"]: with open(filename, 'rb+') as filehandle: filehandle.seek(-1, os.SEEK_END) filehandle.truncate() with open(filename, 'a+') as filehandle: filehandle.write("]];") with open("out/fontsToPaste.txt", "a+") as text_file: text_file.write("</fonts>") print('finished tiling')
def get_brightness(): url = "https://www.athene.fi/olocam/latest.jpg" img = Image.open(requests.get(url, stream=True).raw) brightness = ImageStat.Stat(img).mean[0] return brightness
def is_dark(image: Image.Image) -> Image.Image: """Detect if mean pixel brightness is below 125.""" image_grayscale = image.convert("L") stat = ImageStat.Stat(image_grayscale) return stat.mean[0] < 125
def averageColor(self, hexType=True): color = PILImageStat.Stat(self._image).mean if hexType: color = rgb2hex(color[0], color[1], color[2]) return color
def __init__(self, image, url): npimg = np.array(image) statRGB = ImageStat.Stat(image) r, g, b = statRGB.rms perceivedBrightness = math.sqrt(0.241 * (r**2) + 0.691 * (g**2) + 0.068 * (b**2)) colorfulness = self.image_colorfulness(npimg) greyImg = cv2.cvtColor(npimg, cv2.COLOR_BGR2GRAY) # cpbd algorithm cpbdSharpness = cpbd.compute(greyImg) # num frontal faces in the image face_cascade = cv2.CascadeClassifier( 'haarcascade_frontalface_default.xml') faces_frontal = face_cascade.detectMultiScale(greyImg, 1.1, 35) # num face 'alt' faces in the image face_alt_cascade = cv2.CascadeClassifier( 'haarcascade_frontalface_alt.xml') faces_alt = face_alt_cascade.detectMultiScale(greyImg, 1.1, 20) # num face profile faces in the image face_profile_cascade = cv2.CascadeClassifier( 'haarcascade_profileface.xml') faces_profile = face_profile_cascade.detectMultiScale(greyImg, 1.1, 20) thinEdges = cv2.Canny(greyImg, 20, 60) medEdges = cv2.Canny(greyImg, 50, 100) largeEdges = cv2.Canny(greyImg, 100, 200) # percentage of painting that is thin, med, large edges (an estimate for number of small brushstrokes) pixelCount = len(thinEdges) * len(thinEdges[0]) thinEdgePixels = 0 for row in thinEdges: for col in row: if col > 0: thinEdgePixels += 1 medEdgePixels = 0 for row in medEdges: for col in row: if col > 0: medEdgePixels += 1 largeEdgePixels = 0 for row in largeEdges: for col in row: if col > 0: largeEdgePixels += 1 skyValue = 0 try: skyValue = detect_sky(npimg) except: print('Error during sky detection for: ' + url) self.data = { 'url': url, 'perceivedBrightness': perceivedBrightness, 'colorfulness': colorfulness, 'redLevel': r, 'greenLevel': g, 'blueLevel': b, 'cpbdSharpness': cpbdSharpness, 'numFacesFrontal': len(faces_frontal), 'numFacesAlt': len(faces_alt), 'numFacesProfile': len(faces_profile), 'skyValue': skyValue, 'thinEdgePercentage': thinEdgePixels / pixelCount * 100.0, 'medEdgePercentage': medEdgePixels / pixelCount * 100.0, 'largeEdgePercentage': largeEdgePixels / pixelCount * 100.0 }
def viz(self, im): print 'viz()' means = {'r': [], 'g': [], 'b': [], 'u': []} threshm = {} c2x = {} r2y = {} r = 0 for y in drange(0, im.size[1], self.gridp): y = int(y) r2y[r] = y c = 0 for x in drange(0, im.size[0], self.gridp): x = int(x) c2x[c] = x # TODO: look into using mask # I suspect this is faster imxy = im.crop( (x, y, x + int(self.gridp), y + int(self.gridp))) mean = ImageStat.Stat(imxy).mean mmean = sum(mean[0:3]) / 3.0 means['r'].append(mean[0]) means['g'].append(mean[1]) means['b'].append(mean[2]) means['u'].append(mmean) #print 'x%0.4d y%0.4d: % 8.3f % 8.3f % 8.3f % 8.3f % 8.3f' % (x, y, mean[0], mean[1], mean[2], mean[3], mmean) threshm[(c, r)] = mmean c += 1 r += 1 cols = c rows = r print 'Design grid: %dc x %dr' % (cols, rows) viz = im.copy() draw = ImageDraw.Draw(viz) print 'Annotating' # looks ugly due to non-integer pitch + randomized order #for (c, r), thresh in threshm.iteritems(): for c in xrange(cols): for r in xrange(rows): thresh = threshm[(c, r)] x = c2x[c] y = r2y[r] # The void if thresh <= self.threshl: fill = "black" # Pretty metal elif thresh >= self.threshh: fill = "blue" # WTFBBQ else: fill = "orange" #print 'drawing' draw.rectangle( (x, y, x + int(self.gridp), y + int(self.gridp)), fill=fill) print 'Saving' viz.save(os.path.join(self.outdir, 'viz.png'))
def brightness(im): im = im.convert('L') stat = ImageStat.Stat(im) return stat.rms[0]
def brightness(image): im = Image.open(image) stat = ImageStat.Stat(im) r, g, b = stat.rms return math.sqrt(0.241 * (r**2) + 0.691 * (g**2) + 0.068 * (b**2))