Я пытаюсь взять образец обоев с повторяющимися элементами и обобщить узор на более крупном холсте, используя сопоставление функций ORB или SIFT, чтобы фактически сопоставить образец с его краями и расширить узор. Основополагающий принцип аналогичен сшиванию панорамы, за исключением того, что узор сшивается сам с собой, дополняя все обрезанные элементы по краям.
вот один из примеров типового изображения, которое я я пытаюсь использовать для этого
вот более сложный шаблон, который я также пытаюсь использовать для этого
Для первого примера я пытаюсь чтобы совместить обрезанный верхний космический корабль с полным нижним космическим кораблем, чтобы узор продолжался за исходным краем обоев.
Мне удалось успешно использовать ORB и OpenCV для выполнения простых операций, таких как сшивание изображений. части обоев соедините вместе, чтобы получить образец большего размера. Но мне не удалось взять полную выборку и использовать ее для создания большого узора.
Я попробовал использовать сопоставление признаков ORB, сравнивая центр изображения с каждым краем периферия (см. ниже). Но мне не удалось заставить центральное изображение затем сопоставиться с внешними краями как единое изображение.
import cv2
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# Function to crop the center 90% of the image
def crop_center(image, crop_percentage=0.9):
# Get dimensions of the original image
width, height = image.size
# Calculate dimensions for the cropped image
new_width = int(width * crop_percentage)
new_height = int(height * crop_percentage)
# Calculate the coordinates for the cropping box (centered)
left = (width - new_width) // 2
top = (height - new_height) // 2
right = (width + new_width) // 2
bottom = (height + new_height) // 2
# Crop the image
return image.crop((left, top, right, bottom))
# Function to extract the outer 10% edges of the image
def extract_edges(image, edge_percentage=0.1):
width, height = image.size
# Calculate edge sizes
edge_width = int(width * edge_percentage)
edge_height = int(height * edge_percentage)
# Extract the four edge regions
edges = {
"top": image.crop((0, 0, width, edge_height)),
"bottom": image.crop((0, height - edge_height, width, height)),
"left": image.crop((0, 0, edge_width, height)),
"right": image.crop((width - edge_width, 0, width, height)),
}
return edges
# Function to perform ORB feature matching
def feature_match(cropped_img, edge_img):
# Convert images to grayscale
cropped_img_gray = cv2.cvtColor(np.array(cropped_img), cv2.COLOR_RGB2GRAY)
edge_img_gray = cv2.cvtColor(np.array(edge_img), cv2.COLOR_RGB2GRAY)
# Initialize ORB detector
orb = cv2.ORB_create()
# Detect keypoints and descriptors
kp1, des1 = orb.detectAndCompute(cropped_img_gray, None)
kp2, des2 = orb.detectAndCompute(edge_img_gray, None)
# Create a Brute Force Matcher
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors
matches = bf.match(des1, des2)
# Sort matches based on their distance (lower distance is better)
matches = sorted(matches, key=lambda x: x.distance)
# Draw the top 10 matches
matched_image = cv2.drawMatches(np.array(cropped_img), kp1, np.array(edge_img), kp2, matches[:10], None, flags=2)
# Return the matched image
return matched_image
# Function to display the images in a Colab notebook
def show_image(img, title="Image"):
plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title(title)
plt.axis("off")
plt.show()
# Main function
def find_and_show_matches(image_path):
# Open the original image
img = Image.open(image_path)
# Crop the center 90% of the image
cropped_img = crop_center(img)
# Extract edges (top, bottom, left, right) which represent the outer 10%
edges = extract_edges(img)
# Perform feature matching for each edge and visualize matches
for edge_name, edge_img in edges.items():
matched_img = feature_match(cropped_img, edge_img)
# Display the matches using matplotlib
show_image(matched_img, title=f"Matches with {edge_name} edge")
Подробнее здесь: https://stackoverflow.com/questions/790 ... th-open-cv