Pls modify the following code to match only the best images.

import os
import shutil
import cv2
import numpy as np
from concurrent.futures import ThreadPoolExecutor
from skimage.feature import local_binary_pattern
from skimage.metrics import structural_similarity as ssim

def is_portrait(image):
    return image.shape[0] > image.shape[1]

def preprocess_image(image, target_long_edge=500):
    h, w = image.shape[:2]
    scale = target_long_edge / max(h, w)
    new_h, new_w = int(h * scale), int(w * scale)
    resized_image = cv2.resize(image, (new_w, new_h))
    return resized_image

def safe_read_image(img_path):
    try:
        img = cv2.imread(img_path)
        if img is None:
            raise ValueError(f"Failed to read image: {img_path}")
        return img
    except Exception as e:
        print(f"Error reading {img_path}: {str(e)}")
        return None

def extract_lbp_features(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    lbp = local_binary_pattern(gray, P=8, R=1, method="uniform")
    (hist, _) = np.histogram(lbp.ravel(), bins=np.arange(0, 10), range=(0, 9))
    hist = hist.astype("float32")
    hist /= (hist.sum() + 1e-7)
    return hist

def template_match(img1, img2):
    result = cv2.matchTemplate(img1, img2, cv2.TM_CCOEFF_NORMED)
    _, max_val, _, _ = cv2.minMaxLoc(result)
    return max_val

def compare_color_histograms(img1, img2):
    hist1 = cv2.calcHist([img1], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
    hist2 = cv2.calcHist([img2], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
    
    hist1 = cv2.normalize(hist1, hist1).flatten().astype(np.float32)
    hist2 = cv2.normalize(hist2, hist2).flatten().astype(np.float32)

    return cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)

def compare_images(img1_path, img2_path):
    img1 = safe_read_image(img1_path)
    img2 = safe_read_image(img2_path)

    if img1 is None or img2 is None:
        return 0

    img1_preprocessed = preprocess_image(img1)
    img2_preprocessed = preprocess_image(img2)

    # LBP feature comparison
    lbp1 = extract_lbp_features(img1_preprocessed)
    lbp2 = extract_lbp_features(img2_preprocessed)
    lbp_similarity = 1 - cv2.compareHist(lbp1.astype(np.float32), lbp2.astype(np.float32), cv2.HISTCMP_CHISQR)

    # Template matching
    template_similarity = template_match(img1_preprocessed, img2_preprocessed)

    # SSIM
    gray1 = cv2.cvtColor(img1_preprocessed, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2_preprocessed, cv2.COLOR_BGR2GRAY)
    ssim_score, _ = ssim(gray1, gray2, full=True)

    # Color histogram comparison
    color_similarity = compare_color_histograms(img1_preprocessed, img2_preprocessed)

    # If orientations are different, rotate img1 and compare again
    if is_portrait(img1) != is_portrait(img2):
        img1_rotated = cv2.rotate(img1_preprocessed, cv2.ROTATE_90_CLOCKWISE)
        lbp_rotated = extract_lbp_features(img1_rotated)
        lbp_similarity_rotated = 1 - cv2.compareHist(lbp_rotated.astype(np.float32), lbp2.astype(np.float32), cv2.HISTCMP_CHISQR)
        template_similarity_rotated = template_match(img1_rotated, img2_preprocessed)
        gray_rotated = cv2.cvtColor(img1_rotated, cv2.COLOR_BGR2GRAY)
        ssim_score_rotated, _ = ssim(gray_rotated, gray2, full=True)
        color_similarity_rotated = compare_color_histograms(img1_rotated, img2_preprocessed)

        lbp_similarity = max(lbp_similarity, lbp_similarity_rotated)
        template_similarity = max(template_similarity, template_similarity_rotated)
        ssim_score = max(ssim_score, ssim_score_rotated)
        color_similarity = max(color_similarity, color_similarity_rotated)

    combined_similarity = (lbp_similarity * 0.2 + template_similarity * 0.2 + ssim_score * 0.3 + color_similarity * 0.3)
    return combined_similarity

def compare_folders_and_copy_matches(original_folder, whatsapp_folder, output_folder, threshold=0.7, batch_size=50):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    original_images = [f for f in os.listdir(original_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
    whatsapp_images = [f for f in os.listdir(whatsapp_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]

    def process_batch(batch):
        for original_img in batch:
            original_path = os.path.join(original_folder, original_img)
            best_similarity = 0
            best_match = None

            for whatsapp_img in whatsapp_images:
                whatsapp_path = os.path.join(whatsapp_folder, whatsapp_img)
                try:
                    similarity = compare_images(original_path, whatsapp_path)
                    if similarity > best_similarity:
                        best_similarity = similarity
                        best_match = original_img
                except Exception as e:
                    print(f"Error comparing {original_img} and {whatsapp_img}: {str(e)}")

            if best_similarity > threshold:
                output_path = os.path.join(output_folder, best_match)
                shutil.copy2(original_path, output_path)
                print(f"Matched and copied: {best_match} (Similarity: {best_similarity:.2f})")

    with ThreadPoolExecutor() as executor:
        for i in range(0, len(original_images), batch_size):
            batch = original_images[i:i + batch_size]
            executor.submit(process_batch, batch)

def main():
    original_folder = r'D:\TBD\Nidhi Amulya Maternity Shoot'
    whatsapp_folder = r'D:\TBD\Nidhi Amulya Thumbnails'
    output_folder = r'D:\TBD\Nidhi Amulya Maternity Shoot Selects'
    threshold = 0.7  # Adjust based on testing
    batch_size = 50  # Adjust based on your system's capabilities

    compare_folders_and_copy_matches(original_folder, whatsapp_folder, output_folder, threshold, batch_size)

if __name__ == "__main__":
    main()