Calculating a Velocity Field from Image Data

I am working on a project that involves calculating a velocity vector field using the Particle Image Velocimetry (PIV) technique from two grayscale images. The goal is to implement a function piv() that processes pairs of images to derive velocity vectors (U, V) at defined interrogation points (X, Y). Each interrogation point corresponds to an interrogation window in the first image and a search window in the second image.

The function piv() should:

Load two grayscale images from specified file paths.
Divide each image into small interrogation windows (size_interr_window) and find matching search windows (size_search_window).
Calculate the velocity vector (U, V) for each interrogation point based on the maximum cross-correlation between corresponding windows.
Handle cases where valid search windows cannot be found by setting the velocity vectors to zero.

  • I have implemented the piv() function based on the provided specifications:

  • I ensured that both images are loaded correctly and converted to grayscale if necessary.

  • I iterated through each interrogation point to extract the interrogation and search windows.

  • I used signal.correlate2d() to compute the cross-correlation between the interrogation and search windows and found the maximum correlation index to determine the velocity vector.
    When a valid search window was not found, I explicitly set the velocity vectors (U, V) to zero for those points.
    However, during testing with various images and window sizes:

  • I consistently encountered assertion errors indicating that some velocity vectors were not zero, despite attempting to handle invalid cases by setting them explicitly to zero.

  • I used np.allclose() to verify if the velocity arrays were sufficiently close to zero, but the assertion checks failed.
    Request for Help:

I am seeking assistance in:

Reviewing my implementation of the piv() function to identify any logical errors or oversights that may lead to incorrect velocity vector calculations.
Providing suggestions or alternative approaches to ensure that all velocity vectors are correctly computed and validated.
Offering insights on how to improve handling of cases where valid search windows cannot be found, ensuring robustness in the velocity field calculation.
Your guidance and expertise in solving these issues would be greatly appreciated. Thank you for your assistance!
Here is the code:

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

def loaddata(image_path1, image_path2):
    # Load image data
    image1 = plt.imread(image_path1)
    image2 = plt.imread(image_path2)
    
    # Reduce to grayscale if necessary
    if image1.ndim == 3:
        image1 = np.mean(image1, axis=2)
    if image2.ndim == 3:
        image2 = np.mean(image2, axis=2)
    
    # Check if images have same dimensions
    shape1 = image1.shape
    shape2 = image2.shape
    if shape1 != shape2:
        raise ValueError(f'Input images have different dimensions: {shape1}, {shape2}')
    
    return image1, image2

def velocity_vector(interr_window, search_window):
    # Compute cross-correlation between search_window and interr_window
    correl = signal.correlate2d(search_window, interr_window, mode='same')
    max_index = np.unravel_index(np.argmax(correl), correl.shape)
    center_index = (np.array(search_window.shape) - 1) // 2
    shift = np.array(max_index) - center_index
    return shift

def piv(image_path1, image_path2, size_interr_window=20, size_search_window=None):
    # Ensure size_search_window is at least size_interr_window
    if size_search_window is None:
        size_search_window = size_interr_window
    if size_search_window < size_interr_window:
        raise ValueError('size_search_window must be at least size_interr_window!')
        
    # Load image data
    image1, image2 = loaddata(image_path1, image_path2)
    
    # Calculate number of interrogation points
    rows = image1.shape[0] // size_interr_window
    cols = image1.shape[1] // size_interr_window
    
    # Initialize output arrays for coordinates and velocities
    X, Y = np.meshgrid(np.arange(cols) * size_interr_window + size_interr_window // 2,
                       np.arange(rows) * size_interr_window + size_interr_window // 2)
    U = np.zeros_like(X)
    V = np.zeros_like(Y)
    
    # Check dimensions of output arrays
    assert U.shape == (rows, cols)
    assert V.shape == (rows, cols)
    
    # Iterate over all interrogation points
    for i in range(rows):
        for j in range(cols):
            inter_x_center = i * size_interr_window + size_interr_window // 2
            inter_y_center = j * size_interr_window + size_interr_window // 2
            
            inter_x_start = max(0, inter_x_center - size_interr_window // 2)
            inter_x_end = min(image1.shape[0], inter_x_center + size_interr_window // 2)
            inter_y_start = max(0, inter_y_center - size_interr_window // 2)
            inter_y_end = min(image1.shape[1], inter_y_center + size_interr_window // 2)
            
            interr_window = image1[inter_x_start:inter_x_end, inter_y_start:inter_y_end]
            
            search_x_start = max(0, inter_x_center - size_search_window // 2)
            search_x_end = min(image2.shape[0], inter_x_center + size_search_window // 2)
            search_y_start = max(0, inter_y_center - size_search_window // 2)
            search_y_end = min(image2.shape[1], inter_y_center + size_search_window // 2)
            
            search_window = image2[search_x_start:search_x_end, search_y_start:search_y_end]
            
            if search_window.shape[0] < size_interr_window or search_window.shape[1] < size_interr_window:
                U[i, j] = 0
                V[i, j] = 0
                print(f'Interrogation point ({i},{j}): Invalid velocity vector, setting U,V to 0')
                continue
            
            v = velocity_vector(interr_window, search_window)
            U[i, j] = v[0]
            V[i, j] = v[1]
    
    return X, Y, U, V

if __name__ == "__main__":
    # Test 1: Same images should have zero velocity vectors
    _res0 = piv('img/A045a.tif', 'img/A045a.tif', 20)
    assert np.allclose(_res0[2], 0) and np.allclose(_res0[3], 0)
    
    # Test 2: Different images with specific window sizes
    _res1 = piv('img/B_010.TIF', 'img/B_014.TIF', size_search_window=76, size_interr_window=32)
    assert _res1[2][2, 15] * _res1[2][-2, 15] < 0
    
    print("Tests passed successfully!")


New contributor

Ali Rezaie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật