diff --git a/guess_block_size.py b/guess_block_size.py index 971ca6c..b6a638e 100644 --- a/guess_block_size.py +++ b/guess_block_size.py @@ -5,7 +5,7 @@ from custom_nodes.comfyui_quilting.misc.bse_desc_util import analyze_keypoint_sc from custom_nodes.comfyui_quilting.misc.bse_ft_util import analyze_freq_spectrum -def find_sync_freq(div_weight_pairs, lower, upper): +def find_sync_wavelen(div_weight_pairs, lower, upper): min_distance_sum = float('inf') best_number = lower @@ -50,7 +50,7 @@ def make_guess(dist_weight_pairs, lookup_dims): return default_value print(f"rectified upper bound = {block_size_upper_bound}") - return find_sync_freq(dist_weight_pairs, block_size_lower_bound, block_size_upper_bound) + return find_sync_wavelen(dist_weight_pairs, block_size_lower_bound, block_size_upper_bound) def filter_pairs_by_weight(div_weight_pairs, weight_percentage_threshold): @@ -80,9 +80,11 @@ def guess_nice_block_size(src: np.ndarray) -> int: print(desc_analysis_pairs) # filter very small distances, with respect to the src size - thresh_distance = ceil(min(image.shape[:2]) ** (1 / 4)) - freq_analysis_pairs = [(dst, w) for dst, w in freq_analysis_pairs if dst >= thresh_distance] - desc_analysis_pairs = [(dst, w) for dst, w in desc_analysis_pairs if dst >= thresh_distance] + min_dim = min(image.shape[:2]) + thresh_distance = ceil(min_dim ** (1 / 4)) + block_size_upper_bound = round(min_dim / 1.2) + freq_analysis_pairs = [(dst, w) for dst, w in freq_analysis_pairs if thresh_distance <= dst < block_size_upper_bound] + desc_analysis_pairs = [(dst, w) for dst, w in desc_analysis_pairs if thresh_distance <= dst < block_size_upper_bound] # filter distances whose weight is comparatively low freq_analysis_pairs = filter_pairs_by_weight(freq_analysis_pairs[:5], 20) @@ -100,11 +102,12 @@ def guess_nice_block_size(src: np.ndarray) -> int: if __name__ == "__main__": from cv2 import imread, IMREAD_GRAYSCALE - image_path = "t9.png" + image_path = "t18.png" image = imread(image_path, IMREAD_GRAYSCALE) block_size = guess_nice_block_size(image) print(f"guessed block_size = {block_size}") - # for t9 -> 60 . that is 4 holes (2 and half in the same line) distance & block is not too small - # for t16 -> 55. doesn't look bad & not too small - # for t18 -> 96. about 2x2 apples & not too small - # at a 1st glance seems okay... + # new values + # t9 -> 64 + # t16 -> 55 ( the same as prev. ) + # t18 -> 82 + # seem acceptable at a glance diff --git a/misc/bse_ft_util.py b/misc/bse_ft_util.py index fbfc965..ead1485 100644 --- a/misc/bse_ft_util.py +++ b/misc/bse_ft_util.py @@ -10,58 +10,54 @@ def compute_fft(image): return magnitude_spectrum -def compute_freqs_of_interest(spectrum, max_to_fetch: int = 16): +def compute_wavelens_of_interest(spectrum, max_to_fetch: int = 16): h, w = spectrum.shape[:2] - unique_frequencies = set() - freq_magnitude_pairs = {} + unique_wavelen = set() + wavelen_magnitude_pairs = {} - from math import ceil - freq_thresh = ceil(min(spectrum.shape[:2])**(1/4)) - print(freq_thresh) - - # Flatten the spectrum and get the indices of the sorted magnitudes - flat_indices = np.argsort(spectrum, axis=None)[::-1] # Sort in descending order + # flatten the spectrum and get the indices of the sorted magnitudes + flat_indices = np.argsort(spectrum, axis=None)[::-1] # sort in descending order flat_spectrum = spectrum.flatten() unique_count = 0 - # Skip the first maximum magnitude - start_index = 1 - + start_index = 1 # skip the first maximum magnitude for flat_index in flat_indices[start_index:]: if unique_count >= max_to_fetch: break - # Convert flat index to 2D indices + # convert flat index to 2D indices y, x = np.unravel_index(flat_index, spectrum.shape) magnitude = round(flat_spectrum[flat_index]) - # Calculate the frequency as the maximum absolute distance from the center - freq_y = abs(y - h / 2) - freq_x = abs(x - w / 2) - freq = int(max(freq_y, freq_x)) - if freq < freq_thresh: - continue + # calculate the frequency as the maximum absolute distance from the center + freq_y = abs(y - h / 2) / h # div by h, but that is taken into account in wavelen + freq_x = abs(x - w / 2) / w + # compute wavelen + wavelen_y = 1 / freq_y if freq_y > 0 else 0 # don't return infinity when selecting max + wavelen_x = 1 / freq_x if freq_x > 0 else 0 + wavelen = int(max(wavelen_y, wavelen_x)) - if freq not in unique_frequencies: - unique_frequencies.add(freq) - freq_magnitude_pairs[freq] = magnitude + if wavelen not in unique_wavelen: + unique_wavelen.add(wavelen) + wavelen_magnitude_pairs[wavelen] = magnitude unique_count += 1 else: - if magnitude > freq_magnitude_pairs[freq]: - freq_magnitude_pairs[freq] = magnitude + if magnitude > wavelen_magnitude_pairs[wavelen]: + wavelen_magnitude_pairs[wavelen] = magnitude - return list(freq_magnitude_pairs.items()) + return list(wavelen_magnitude_pairs.items()) def analyze_freq_spectrum(image, max_components=16): magnitude_spectrum = compute_fft(image) - af = compute_freqs_of_interest(magnitude_spectrum, max_components) - return af + wlen_mag_pairs = compute_wavelens_of_interest(magnitude_spectrum, max_components) + print(f"sorted wavelens = {wlen_mag_pairs}") + return wlen_mag_pairs if __name__ == "__main__": - image_path = "../t9.png" + image_path = "../t16.png" image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) data = analyze_freq_spectrum(image, max_components=10) print(data)