def generate_ycc_from_rgb(): cs = ColorSpace() increment = 48 with open('rgb_ycc.txt', 'w') as fh: for red in range(0, 256, increment): for green in range(0, 256, increment): for blue in range(0, 256, increment): lum, cb, cr = cs.to_ycc(red, green, blue) fh.write('%d,%d,%d,%.2f,%.2f,%.2f\n' % \ (red, green, blue, lum, cb, cr)) fh.flush()
def get_ycc_subimages(self): if self.rgb_image is None: self.rgb_image = Image.open(self.image_path) self.rgb_array = np.asarray(self.rgb_image) if self.ycc_array is None: color_space = ColorSpace() red = self.rgb_array[:,:,0] green = self.rgb_array[:,:,1] blue = self.rgb_array[:,:,2] lum, cb, cr = color_space.to_ycc(red, green, blue) x,y = lum.shape self.ycc_array = np.zeros( (x,y,3), dtype=lum.dtype) self.ycc_array[:,:,0] = lum self.ycc_array[:,:,1] = cb self.ycc_array[:,:,2] = cr return decompose_subimages(self.ycc_array)
def get_dcts(self): if self.rgb_image is None: self.rgb_image = Image.open(self.image_path) self.rgb_array = np.asarray(self.rgb_image) if self.ycc_array is None: color_space = ColorSpace() red = self.rgb_array[:,:,0] green = self.rgb_array[:,:,1] blue = self.rgb_array[:,:,2] lum, cb, cr = color_space.to_ycc(red, green, blue) x,y = lum.shape self.ycc_array = np.zeros( (x,y,3), dtype=lum.dtype) self.ycc_array[:,:,0] = lum self.ycc_array[:,:,1] = cb self.ycc_array[:,:,2] = cr if self.ycc_sub_images is None: self.ycc_sub_images = self._decompose_ycc() ret_dcts = [] for window in self.ycc_sub_images: lum, _, _ = window[:, :, 0], window[:,:,1], window[:,:,2] # switched to scipy dct for performance lum_dct = dct(lum, type=2, norm='ortho') #lum_dct = two_dim_DCT(_lum_pixels) # TODO(tierney): Technically, need to subsample Cb and Cr before # DCT. These Cb and Cr values should be treated as unrealistic until # subsampling before the DCT step. #cb_dct = two_dim_DCT(_cb_pixels) #cr_dct = two_dim_DCT(_cr_pixels) ret_dcts.append(lum_dct) return numpy.array(ret_dcts)
def main(argv): # visualize_ycc() # return # Parse arguments. parser = argparse.ArgumentParser( prog='SixBits', formatter_class=argparse.ArgumentDefaultsHelpFormatter) args = parser.parse_args() _ = args # Colors in this dictionary are describe in YCbCr space. color = {'white' : (255, 128, 128), 'black' : (0, 128, 128), 'yellow' : (226, 1, 149), 'blue' : (29, 255, 107), 'red' : (76, 85, 255), 'cyan' : (179, 171, 1), 'green' : (150, 44, 21), 'magenta' : (105, 212, 235)} all_values = [] num_discretizations = 9 side_discrets = 4 import YccLevels all_values = YccLevels.get_discrete_values() all_values = list(set(all_values)) # to_remove = [ # (100, 72, 57), # (132, 54, 215), # (147, 45, 205), # (100, 215, 57), # ( 85, 224, 67), # (132, 197, 216), # (147, 188, 205) # ] # for _ in to_remove: # all_values.remove(_) # all_values.remove((128, 128, 128)) # Remove most ambiguious chunks. print 'Values' for _val in sorted(all_values): print ' ', _val num_values = len(all_values) import math print 'Number of distinct values: %d (%.2f bits).' % \ (num_values, math.log(num_values, 2)) from scipy.spatial.distance import pdist, euclidean, wminkowski, cosine distances = pdist(all_values) count = 0 idx_val = {} for i in range(num_values): for j in range(i + 1, num_values): idx_val[count] = (i, j) count += 1 # for idx in idx_val: # first, second = idx_val[idx] # if distances[idx] < 28: # print idx, all_values[first], all_values[second], distances[idx] possible_values = all_values IMAGE_WIDTH = 8 IMAGE_HEIGHT = 8 im = Image.new('YCbCr', (IMAGE_WIDTH, IMAGE_HEIGHT)) pixels = im.load() original_vals = [] for row in range(0, IMAGE_HEIGHT, 2): for col in range(0, IMAGE_WIDTH, 2): val = tuple(map(int, random.choice(possible_values))) original_vals.append(val) print 'Written:', val pixels[row, col] = val pixels[row + 1, col] = val pixels[row, col + 1] = val pixels[row + 1, col + 1] = val original_vals.reverse() QUALITY = 75 im.save('test.jpg', quality = QUALITY) print 'ALL VALUES', all_values opened_im = Image.open('test.jpg') pixels = opened_im.load() for row in range(0, IMAGE_HEIGHT, 2): for col in range(0, IMAGE_WIDTH, 2): vals = {} for idx in range(3): val = 0 val += pixels[row, col][idx] val += pixels[row + 1, col][idx] val += pixels[row, col + 1][idx] val += pixels[row + 1, col + 1][idx] val /= 4.0 vals[idx] = val red = vals[0] green = vals[1] blue = vals[2] extracted = ColorSpace.to_ycc(red, green, blue) print ' Extracted', extracted _best_val = 1000 _best_match = () for vect in all_values: vect = map(int, map(round, vect)) dist = wminkowski(extracted, vect, 2, [5, 1, 1]) print extracted, vect, dist if dist < _best_val: _best_val = dist _best_match = vect print ' Best Val', _best_val, _best_match _orig = list(original_vals.pop()) _best_match = map(int, _best_match) # map(int, _min_vect) if _orig != _best_match: _mismatch_print = 'Mismatch at (%3d, %3d):\n' % (row, col) orig_extracted_dist = wminkowski(_orig, extracted, 2, [5, 1, 1]) _mismatch_print += ' original = (%3d, %3d, %3d) %6.2f\n' % tuple(_orig + [orig_extracted_dist]) best_match_dist = wminkowski(_orig, _best_match, 2, [5, 1, 1]) _mismatch_print += ' closest = (%3d, %3d, %3d) %6.2f\n' % tuple(_best_match + [best_match_dist]) _mismatch_print += ' extracted = (%3d, %3d, %3d)\n' % tuple(map(int, map(round, extracted))) print _mismatch_print
message_base8 += octal_val.replace(' ','0') print message print message_base8, len(message_base8) print indices mat = numpy.zeros((8,8)) img_buffer = [] print 'Original RGB' for row in range(0, 8, 1): for col in range(0, 8, 1): value = thresholds[message_base8[row*8 + col]] red = green = blue = value print '%5.1f' % value, y, cb, cr = ColorSpace.to_ycc(red, green, blue) mat[row,col] = float(y) img_buffer.append(int(y)) # mat[row+1,col] = float(y) # mat[row,col+1] = float(y) # mat[row+1,col+1] = float(y) print print from PIL import Image print str(img_buffer) im = Image.new('RGB', (16,16)) pixels = im.load() # for i in range(0, 16, 2): # for j in range(0, 16, 2): # rgb = (img_buffer[(i/2)*8 + (j/2)],