def get_motion_vectors(self, image2, searcher, MAD_threshold = None): """ 1) Divide self.image into blocks of 8x8 pixels 2) for each block: 4) get the X and Y 5) search block in image2 from X and Y, moving from 0 to P pixel right, left, top, bottom 6) block found? 7) if yes, get the new X and Y 8) if no, return 0 """ if isinstance(self.image, QImage): image1 = ImageConverter.qtimage_to_pil_image(self.image) else: image1 = self.image images1_pixels = image1.load() if isinstance(image2, QImage): image2 = ImageConverter.qtimage_to_pil_image(image2) images2_pixels = image2.load() width = image1.size[0] height = image1.size[1] vectors = [] for block_x_num in range(0, width/searcher.block_size): block_x_pos = searcher.block_size*block_x_num for block_y_num in range(0, height/searcher.block_size): block_y_pos = searcher.block_size*block_y_num (new_x, new_y, MAD, MAD_checks_count) = searcher.search(images1_pixels, block_x_pos, block_y_pos, images2_pixels) valid_vector = True if MAD_threshold and MAD > MAD_threshold: #Discard the vector if the MAD is over ranged valid_vector = False if valid_vector: #if (block_x_pos != new_x) or (block_y_pos != new_y): vector = { 'x': block_x_pos, 'y': block_y_pos, 'to_x' : new_x, 'to_y': new_y, 'MAD': MAD, 'MAD_checks_count': MAD_checks_count} vectors.append(vector) return vectors
def get_image2_luminance(self): if self.image_2: if not self.image_2_luminance: start_time = time.time() self.image_2_luminance = ImageConverter.luminance_qimage(self.image_2) klog("La conversione in luminanza ha impiegato: %.2f secondi" % (time.time()-start_time)) return self.image_2_luminance else: return None
def search(self, image1_pixels, x_start, y_start, image2_pixels): self.reset_search() block_size = self.block_size pass_step = self.pass_step subimage_1_pixels = ImageConverter.sub_pixels(image1_pixels, x_start, y_start, x_start+block_size, y_start+block_size) p = pass_step ds = p/2 s = 1 xs = x_start ys = y_start xs_min = -1 ys_min = -1 best_local_MAD = 10000 best_global_MAD = 10000 best_x = -1 best_y = -1 klog("Check block from %d, %d" %(x_start, y_start)) while ds >= 1: for x in [xs, xs+ds, xs-ds]: for y in [ys, ys+ds, ys-ds]: if not ImageComparator.is_valid_coordinate(x, y, block_size, image2_pixels): continue MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, x, y, x+block_size, y+block_size) if MAD < best_local_MAD: best_local_MAD = MAD xs_min = x ys_min = y #Check if the local MAD is the best global MAD if MAD < best_global_MAD: best_global_MAD = MAD best_x = x best_y = y s += 1 ds -= 1 xs = xs_min ys = ys_min print "-" return best_x, best_y, best_global_MAD, self._MAD_checks_count
def calculate_MAD(self, subimage_1_pixels, image2_pixels, x, y, to_x, to_y): """ subimage_1_pixels is the the image to be found image2_pixels is the pixels of the image that should contain sub_pixels_1 x, y is the upper coordinate of pixels_2 to be checked x+block_size, y+block_size is the lower coordinate of pixels_2 to be checked """ MAD = self._get_saved_MAD(x, y) if not MAD: subimage_2_pixels = ImageConverter.sub_pixels(image2_pixels, x, y, to_x, to_y) #Calculate the MAD MAD = ImageComparator.calculate_MAD_v2(subimage_1_pixels, subimage_2_pixels) self._coordinates_checked["%dx%d" %(x,y)] = MAD self._MAD_checks_count += 1 #klog("%d,%d\t\t\t\tMAD-> %f" %(x,y, MAD)) return MAD
def _draw_compressed_frame2(self): if len(self.vectors) > 0: self._draw_motion_vectors() zero_vectors_blocks_count = 0 new_blocks_count = 0 moved_vectors_blocks_count = 0 self._draw_frame(self.image_2, self.ui.frame2CompressedGraphicsView) scene = self.ui.frame2CompressedGraphicsView.scene() image2_new = QImage(self.image_2) sameBlockPen = QPen(Qt.black, 1, Qt.SolidLine) movedBlockPen = QPen(Qt.green, 1, Qt.SolidLine) for v in self.vectors: x = int(v["x"]) y = int(v["y"]) to_x = int(v["to_x"]) to_y = int(v["to_y"]) MAD = v["MAD"] if x == to_x and y == to_y: #The block is the same of the previous frame. Transmit a zero vector zero_vectors_blocks_count += 1 scene.addRect(x, y, self.get_block_size(), self.get_block_size(), sameBlockPen, QBrush(Qt.SolidPattern)) else: if MAD < self.ui.MADThresholdSpingBox.value(): #The block is moved moved_vectors_blocks_count += 1 scene.addRect(x, y, self.get_block_size(), self.get_block_size(), movedBlockPen, QBrush(Qt.green, Qt.SolidPattern)) moved_block_image = self.image_1.copy(x,y, self.get_block_size(), self.get_block_size()) ImageConverter.draw_image_into_image(moved_block_image, image2_new, to_x, to_y) else: #A new block of the frame is needed new_blocks_count += 1 #Draw the reconstructed Frame scene = QGraphicsScene() scene.addPixmap(QPixmap.fromImage(image2_new)) self.ui.frame2ReconstructedGraphicsView.setScene(scene) #Show the statistics zero_vectors_blocks_percent = (zero_vectors_blocks_count*100/len(self.vectors)) new_blocks_percent = (new_blocks_count*100/len(self.vectors)) moved_vectors_blocks_percent = (moved_vectors_blocks_count*100/len(self.vectors)) compression_ratio = 100 - new_blocks_percent - moved_vectors_blocks_percent/3 self.ui.zeroVectorsPercentLabel.setText("%d %%" %zero_vectors_blocks_percent ) self.ui.newBlocksPercentLabel.setText("%d %%" % new_blocks_percent) self.ui.movedVectorsPercentLabel.setText("%d %%" % moved_vectors_blocks_percent) self.ui.compressionRatioLabel.setText("%d %%" %compression_ratio) total_mads_checked = 0 for v in self.vectors: total_mads_checked += v["MAD_checks_count"] self.ui.MADsCheckedLabel.setText("%d" %total_mads_checked) #Calculate the PSNR PSNR = ImageComparator.calculate_PSNR(ImageConverter.qtimage_to_pil_image(self.image_2), ImageConverter.qtimage_to_pil_image(image2_new), self.image_2.width(), self.image_2.height()) self.ui.psnrFrame2Label.setText("%d" % PSNR)
def search(self, image1_pixels, x_start, y_start, image2_pixels): self.reset_search() block_size = self.block_size pass_step = self.pass_step subimage_1_pixels = ImageConverter.sub_pixels(image1_pixels, x_start, y_start, x_start+block_size, y_start+block_size) p = pass_step ds = p/2+1 s = 1 xs = x_start ys = y_start best_local_MAD = 10000 xs_min = -1 ys_min = -1 best_local_a_MAD = 10000 xs_a_min = -1 ys_a_min = -1 best_global_MAD = 10000 best_x = -1 best_y = -1 #klog("Check block from %d, %d" %(x_start, y_start)) while True: for (x,y) in [ (xs,ys), (xs-ds,ys), (xs+ds,ys) ]: if not ImageComparator.is_valid_coordinate(x, y, block_size, image2_pixels): continue MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, x, y, x+block_size, y+block_size) if MAD < best_local_a_MAD: best_local_a_MAD = MAD xs_a_min = x ys_a_min = y #Check if the local MAD is the best global MAD if MAD < best_global_MAD: best_global_MAD = MAD best_x = x best_y = y for (x,y) in [ (xs_a_min,ys_a_min), (xs_a_min,ys_a_min-ds), (xs_a_min, ys_a_min+ds) ]: if not ImageComparator.is_valid_coordinate(x, y, block_size, image2_pixels): continue #Calculate the MAD MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, x, y, x+block_size, y+block_size) if MAD < best_local_MAD: best_local_MAD = MAD xs_min = x ys_min = y #Check if the local MAD is the best global MAD if MAD < best_global_MAD: best_global_MAD = MAD best_x = x best_y = y if ds == 1: break s += 1 ds = math.ceil( ds/2 ) # klog("ds: %d" %(ds)) xs = xs_min ys = ys_min best_local_MAD = 10000 #reset best_local_a_MAD = 10000 #reset #klog("-") #klog("MADs check count: %d" %MAD_checks_count) return best_x, best_y, best_global_MAD, self._MAD_checks_count
def search(self, image1_pixels, x_start, y_start, image2_pixels): self.reset_search() block_size = self.block_size pass_step = self.pass_step #subimage_1 = image1.copy(x_start, y_start, block_size, block_size) subimage_1_pixels = ImageConverter.sub_pixels(image1_pixels, x_start, y_start, x_start+block_size, y_start+block_size) p = pass_step ds = math.pow(2, math.floor( math.log(p,2))-1 ) s = 1 xs = x_start ys = y_start xs_min = -1 ys_min = -1 best_local_MAD = 10000 best_global_MAD = 10000 best_x = -1 best_y = -1 while ds >= 1: if ds != 1: for (x,y) in [(xs, ys), (xs-ds,ys), (xs+ds, ys), (xs, ys+ds), (xs,ys-ds)]: if not ImageComparator.is_valid_coordinate(x, y, block_size, image2_pixels): continue MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, x, y, x+block_size, y+block_size) if MAD < best_local_MAD: best_local_MAD = MAD xs_min = x ys_min = y #Check if the local MAD is the best global MAD if MAD < best_global_MAD: best_global_MAD = MAD best_x = x best_y = y s += 1 #Check if the xs_min and ys_min are the central point of the fives checked if xs_min == xs and ys_min == ys: ds /= 2 xs = xs_min ys = ys_min else: #ds==1 last step for x in [xs, xs+ds, xs-ds]: for y in [ys, ys+ds, ys-ds]: #TODO: CODE HERE IS COPY-PASTED!! THIS SUCKS! secondo me va bene! if not ImageComparator.is_valid_coordinate(x, y, block_size, image2_pixels): continue MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, x, y, x+block_size, y+block_size) if MAD < best_local_MAD: best_local_MAD = MAD xs_min = x ys_min = y #Check if the local MAD is the best global MAD if MAD < best_global_MAD: best_global_MAD = MAD best_x = x best_y = y ds = 0 s += 1 print "ds: %d" %ds return best_x, best_y, best_global_MAD, self._MAD_checks_count
def search(self, image1_pixels, x_start, y_start, image2_pixels): self.reset_search() block_size = self.block_size margin_size = self.margin_size best_MAD = 1000000 best_x = None best_y = None subimage_1_pixels = ImageConverter.sub_pixels(image1_pixels, x_start, y_start, x_start+block_size, y_start+block_size) #Start with the center if ImageComparator.is_valid_coordinate(x_start, y_start, block_size, image2_pixels): MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, x_start, y_start, x_start+block_size, y_start+block_size) if MAD < best_MAD: #klog("Best MAD found: %f, at (%f,%f)" % (MAD, px, py)) best_MAD = MAD best_x = x_start best_y = y_start if best_MAD == 0: return best_x, best_y, best_MAD, self._MAD_checks_count for py in range(y_start-margin_size, y_start+margin_size): if py < 0: continue #il blocco esce in su dall'immagine, avanza con il prossimo py incrementato #CHECK!! if not ImageComparator.is_valid_coordinate(0, py, block_size, image2_pixels): break #il blocco esce in giu dall'immagine, esci for px in range(x_start-margin_size, x_start+margin_size): if px < 0: continue #il blocco esce a sinistra dall'immagine, avanza con il prossimo px incrementato #CHECK!! if not ImageComparator.is_valid_coordinate(px, py, block_size, image2_pixels): break #il blocco esce in giu dall'immagine, esci #if px+block_size > image2.width(): # break #il blocco esce a destra dall'immagine, esci #klog("Valuating block (%f,%f)" %(px, py)) MAD = self.calculate_MAD(subimage_1_pixels, image2_pixels, px, py, px+block_size, py+block_size) if MAD < best_MAD: #klog("Best MAD found: %f, at (%f,%f)" % (MAD, px, py)) best_MAD = MAD best_x = px best_y = py if best_MAD == 0: return best_x, best_y, best_MAD, self._MAD_checks_count return best_x, best_y, best_MAD, self._MAD_checks_count
def grayscaled_image(self): if not self._grayscaled_image: self._grayscaled_image = ImageConverter.luminance_image(self.image()) return self._grayscaled_image