Technical Notes Collection: OpenCV, PyTorch, and Causal Inference

DoWhy Library for Causal Inference

The DoWhy library provides a structured approach to causal inference, enabling researchers to estimate causal effects from observational data.

Installation:

pip install dowhy

Basic usage example:

import numpy as np
import pandas as pd
from dowhy import CausalModel
import dowhy.datasets

# Generate synthetic dataset
random_effect = 1 if np.random.uniform() > 0.5 else 0
data_dict = dowhy.datasets.xy_dataset(10000, effect=random_effect, sd_error=0.2)
df = data_dict['df']

# Define causal model with treatment, outcome, and common causes
causal_model = CausalModel(
    data=df,
    treatment=data_dict["treatment_name"],
    outcome=data_dict["outcome_name"],
    common_causes=data_dict["common_causes_names"]
)
causal_model.view_model(layout="dot")

Key parameters:

  • data: DataFrame containing all relevant variables including treatment, outcome, common causes, and instruments
  • treatment: Variable name representing the intervention whose causal effect we want to measure
  • outcome: Variable name representing the outcome of interest
  • common_causes: List of confounding variable names that affect both treatment and outcome
  • instruments: Optional list of instrumental variables for addressing endogeneity

OpenCV DNN Module for Deep Learning Inference

The OpenCV DNN module supports inference with models from TensorFlow, Darknet, PyTorch, and other frameworks. This section covers various computer vision applications.

Face Detection with Caffe Models

import numpy as np
import cv2

if __name__ == '__main__':
    confidence_threshold = 0.5
    image_path = 'input.jpg'
    prototxt_file = 'deploy.prototxt'
    model_file = 'res10_300x300_ssd_iter_140000_fp16.caffemodel'

    # Load pre-trained model
    print("[INFO] loading model...")
    network = cv2.dnn.readNetFromCaffe(prototxt_file, model_file)

    # Prepare input image
    image = cv2.imread(image_path)
    height, width = image.shape[:2]
    blob = cv2.dnn.blobFromImage(
        cv2.resize(image, (300, 300)), 1.0,
        (300, 300), (104.0, 177.0, 123.0)
    )

    # Perform inference
    print("[INFO] computing object detections...")
    network.setInput(blob)
    detections = network.forward()

    # Process detection results
    for i in range(0, detections.shape[2]):
        confidence = detections[0, 0, i, 2]
        if confidence > confidence_threshold:
            box = detections[0, 0, i, 3:7] * np.array([width, height, width, height])
            start_x, start_y, end_x, end_y = box.astype("int")
            
            label = "{:.2f}%".format(confidence * 100)
            y_coord = start_y - 10 if start_y - 10 > 10 else start_y + 10
            
            cv2.rectangle(image, (start_x, start_y), (end_x, end_y), (0, 0, 255), 2)
            cv2.putText(image, label, (start_x, y_coord),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)

    cv2.imshow("Output", image)
    cv2.imwrite("result.jpg", image)
    cv2.waitKey(0)

Human Pose Estimation with MediaPipe

import cv2
import mediapipe as mp
import time

mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
mp_draw = mp.solutions.drawing_utils

cap = cv2.VideoCapture('video.mp4')
previous_time = 0

while True:
    success, frame = cap.read()
    if not success:
        break
    
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = pose.process(frame_rgb)
    
    if results.pose_landmarks:
        mp_draw.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
        
        frame_height, frame_width, _ = frame.shape
        for idx, landmark in enumerate(results.pose_landmarks.landmark):
            center_x = int(landmark.x * frame_width)
            center_y = int(landmark.y * frame_height)
            cv2.circle(frame, (center_x, center_y), 5, (255, 0, 0), cv2.FILLED)
    
    current_time = time.time()
    fps = 1 / (current_time - previous_time)
    previous_time = current_time
    
    cv2.putText(frame, str(int(fps)), (50, 50), 
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 3)
    cv2.imshow("Frame", frame)
    
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

YOLOv3 Object Detection

import numpy as np
import cv2
import time

# Model configuration
weights_path = './yolov3-tiny.weights'
config_path = './yolov3-tiny.cfg'
labels_path = './classes.names'

class_labels = open(labels_path).read().strip().split("\n")
color_palette = [(255, 255, 0), (255, 0, 255), (0, 255, 255), (0, 255, 0)]
min_confidence = 0.3

# Load Darknet model
network = cv2.dnn.readNetFromDarknet(config_path, weights_path)

# Process video
cap = cv2.VideoCapture('input_video.h264')

while True:
    bounding_boxes = []
    confidence_scores = []
    class_ids = []
    
    start_time = time.time()
    ret, frame = cap.read()
    
    if not ret:
        break
    
    frame = cv2.resize(frame, (744, 416), interpolation=cv2.INTER_CUBIC)
    img_height, img_width = frame.shape[:2]
    
    # Get output layer names
    layer_names = network.getLayerNames()
    output_layers = network.getUnconnectedOutLayers()
    layer_indices = [layer_names[i[0] - 1] for i in output_layers]
    
    # Create input blob
    blob = cv2.dnn.blobFromImage(frame, 1/255.0, (416, 416), swapRB=True, crop=False)
    network.setInput(blob)
    layer_outputs = network.forward(layer_indices)
    
    # Process outputs
    for output in layer_outputs:
        for detection in output:
            scores = detection[5:]
            class_id = np.argmax(scores)
            score = scores[class_id]
            
            if score >= min_confidence:
                center_x = int(detection[0] * img_width)
                center_y = int(detection[1] * img_height)
                box_width = int(detection[2] * img_width)
                box_height = int(detection[3] * img_height)
                
                x = int(center_x - box_width / 2)
                y = int(center_y - box_height / 2)
                
                bounding_boxes.append([x, y, box_width, box_height])
                confidence_scores.append(float(score))
                class_ids.append(class_id)
    
    # Apply Non-Maximum Suppression
    indices = cv2.dnn.NMSBoxes(bounding_boxes, confidence_scores, 0.2, 0.3)
    
    # Draw results
    if len(indices) > 0:
        for idx in indices.flatten():
            x, y, w, h = bounding_boxes[idx]
            color = color_palette[class_ids[idx] % len(color_palette)]
            cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
            label = "{}: {:.3f}".format(class_labels[class_ids[idx]], confidence_scores[idx])
            cv2.putText(frame, label, (x, y - 5), 
                        cv2.FONT_HERSHEY_SIMPLEX, 0.3, color, 1)
    
    cv2.namedWindow('Detection', cv2.WINDOW_NORMAL)
    cv2.imshow('Detection', frame)
    
    elapsed_time = time.time() - start_time
    print(f'fps: {1/elapsed_time:.2f}')
    
    if cv2.waitKey(1) & 0xff == 27:
        break

cap.release()
cv2.destroyAllWindows()

Image Processing Operations

Grayscale Conversion and Thresholding

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# Grayscale conversion
img = cv.imread("lena.png")
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Alternative: load as grayscale directly
img = cv.imread("lena.png", cv.IMREAD_GRAYSCALE)

# Simple thresholding types
ret1, binary = cv.threshold(gray_img, 127, 255, cv.THRESH_BINARY)
ret2, binary_inv = cv.threshold(gray_img, 127, 255, cv.THRESH_BINARY_INV)
ret3, trunc = cv.threshold(gray_img, 127, 255, cv.THRESH_TRUNC)
ret4, tozero = cv.threshold(gray_img, 127, 255, cv.THRESH_TOZERO)
ret5, tozero_inv = cv.threshold(gray_img, 127, 255, cv.THRESH_TOZERO_INV)

titles = ['Original', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [gray_img, binary, binary_inv, trunc, tozero, tozero_inv]

for i in range(6):
    plt.subplot(2, 3, i+1)
    plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()

Image Morphological Operations

import numpy as np
import cv2

if __name__ == '__main__':
    source_img = cv2.imread('bird.jpeg', cv2.COLOR_BGR2LAB)
    
    kernel = np.ones((3, 3), np.uint8)
    eroded = cv2.erode(source_img, kernel, iterations=1)
    dilated = cv2.dilate(source_img, kernel, iterations=1)
    
    combined = np.concatenate((source_img, eroded, dilated), axis=1)
    cv2.imshow('Comparison: Origin, Erosion, Dilation', combined)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def opening_operation(img):
    """Morphological opening: erosion followed by dilation"""
    kernel = np.ones((3, 3), np.uint8)
    temp = cv2.erode(img, kernel, iterations=1)
    result = cv2.dilate(temp, kernel, iterations=1)
    return result

def closing_operation(img):
    """Morphological closing: dilation followed by erosion"""
    kernel = np.ones((3, 3), np.uint8)
    temp = cv2.dilate(img, kernel, iterations=1)
    result = cv2.erode(temp, kernel, iterations=1)
    return result

Contour Detection and Drawing

import cv2 as cv

img = cv.imread("contours.jpg", flags=1)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
_, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY_INV)

contours, hierarchy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
result = cv.drawContours(img, contours, -1, (0, 0, 255), 2)

cv.imshow("Contours", result)
cv.waitKey(0)

Connected Component Analysis

import cv2
import numpy as np
import matplotlib.pyplot as plt

def closing_operation(img):
    kernel = np.ones((3, 3), np.uint8)
    temp = cv2.dilate(img, kernel, iterations=1)
    return cv2.erode(temp, kernel, iterations=1)

def display_results(images_dict):
    idx = 0
    for title, img in images_dict.items():
        plt.subplot(2, 3, idx+1)
        plt.imshow(img, 'gray')
        plt.title(title)
        plt.xticks([]), plt.yticks([])
        idx += 1
    plt.show()

if __name__ == '__main__':
    source = cv2.imread('duck.jpeg', -1)
    processed = source.copy()
    
    gray = cv2.cvtColor(processed, cv2.COLOR_BGR2GRAY)
    gray_closed = closing_operation(gray)
    _, binary = cv2.threshold(gray_closed, 127, 255, cv2.THRESH_BINARY)
    
    num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary)
    sorted_stats = sorted(stats, key=lambda s: s[-1], reverse=False)
    largest_component = sorted_stats[-2]
    
    cv2.rectangle(
        processed,
        (largest_component[0], largest_component[1]),
        (largest_component[0] + largest_component[2], 
         largest_component[1] + largest_component[3]),
        (255, 0, 0), 3
    )
    
    images = {
        'Original': source,
        'Grayscale': gray,
        'After Closing': gray_closed,
        'Binary': binary,
        'With Bounding Box': processed
    }
    display_results(images)

Color Space Conversions and Filtering

import numpy as np
import cv2

def filter_color_region(image_path):
    image = cv2.imread(image_path, -1)
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    
    lower_bound = np.array([0, 20, 100])
    upper_bound = np.array([10, 255, 255])
    
    mask = cv2.inRange(hsv, lower_bound, upper_bound)
    result = cv2.bitwise_and(image, image, mask=mask)
    
    combined = np.concatenate((image, result), axis=1)
    cv2.imshow('Comparison', combined)
    cv2.waitKey()
    cv2.destroyAllWindows()

# Histogram equalization for color images
def enhance_image_contrast(image_path):
    b, g, r = cv2.split(cv2.imread(image_path, -1))
    
    b_eq = cv2.equalizeHist(b)
    g_eq = cv2.equalizeHist(g)
    r_eq = cv2.equalizeHist(r)
    
    enhanced = cv2.merge((b_eq, g_eq, r_eq))
    
    original = cv2.imread(image_path, -1)
    combined = np.concatenate((original, enhanced), axis=1)
    cv2.imwrite('enhanced.jpg', combined)
    cv2.imshow('Enhanced', combined)
    cv2.waitKey()
    cv2.destroyAllWindows()

Gradient Operators (Sobel)

import cv2 as cv

img = cv.imread("lena.png", flags=1)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

sobel_x = cv.Sobel(gray, cv.CV_16S, 1, 0)
sobel_y = cv.Sobel(gray, cv.CV_16S, 0, 1)

abs_x = cv.convertScaleAbs(sobel_x)
abs_y = cv.convertScaleAbs(sobel_y)

combined = cv.addWeighted(abs_x, 0.5, abs_y, 0.5, 0)

cv.imshow("Sobel Gradient", combined)
cv.waitKey(0)

Affine and Perspective Transforms

import cv2
import numpy as np

if __name__ == '__main__':
    src_img = cv2.imread('source.jpg')
    pts_source = np.float32([[50, 50], [200, 50], [50, 200]])
    pts_dest = np.float32([[50, 100], [200, 50], [100, 250]])
    
    transform_matrix = cv2.getAffineTransform(pts_source, pts_dest)
    result = cv2.warpAffine(src_img, transform_matrix, src_img.shape[:2])
    
    cv2.imshow("Original", src_img)
    cv2.imshow("Affine", result)
    cv2.waitKey(0)

# Homography for perspective correction
if __name__ == '__main__':
    src_img = cv2.imread('source_image.jpg')
    src_points = np.array([[0, 0], [570, 0], [570, 1078], [0, 1078]])
    
    dst_img = cv2.imread('destination_image.jpg')
    dst_points = np.array([[63, 285], [378, 224], [427, 689], [84, 820]])
    
    img_height, img_width = dst_img.shape[:2]
    homography, _ = cv2.findHomography(src_points, dst_points)
    
    warped = cv2.warpPerspective(src_img, homography, (img_width, img_height))
    
    cv2.imshow('Source, Destination, Warped', 
                np.concatenate((src_img[0:img_height, 0:img_width, 0:3], 
                                dst_img, warped), axis=1))
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Feature Detection (Harris Corner Detection)

import cv2
import numpy as np

def close_operation(img):
    kernel = np.ones((5, 5), np.uint8)
    temp = cv2.dilate(img, kernel, iterations=1)
    return cv2.erode(temp, kernel, iterations=1)

def extract_green_regions(img):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_green = np.array([50, 100, 50])
    upper_green = np.array([70, 255, 255])
    
    lower_red = np.array([0, 20, 100])
    upper_red = np.array([10, 255, 255])
    
    mask = cv2.inRange(hsv, lower_red, upper_red)
    return close_operation(cv2.bitwise_and(img, img, mask=mask))

if __name__ == '__main__':
    original = cv2.imread('tower.jpeg')
    processed = original.copy()
    
    no_green = extract_green_regions(processed)
    
    gray = cv2.cvtColor(no_green, cv2.COLOR_BGR2GRAY)
    gray_float = np.float32(gray)
    
    corners = cv2.cornerHarris(gray_float, 2, 3, 0.04)
    corners = cv2.dilate(corners, None)
    
    processed[corners > 0.01 * corners.max()] = [0, 0, 255]
    
    combined = np.concatenate((original, no_green, processed), axis=1)
    cv2.imwrite('result.jpg', combined)
    cv2.imshow('Results', combined)
    cv2.waitKey()
    cv2.destroyAllWindows()

Feature Matching with ORB

import cv2
import numpy as np

if __name__ == '__main__':
    img1 = cv2.imread('tower01.jpg', -1)
    img2 = cv2.imread('tower02.jpg', -1)
    
    detector = cv2.ORB_create(nfeatures=500)
    kp1, des1 = detector.detectAndCompute(img1, None)
    kp2, des2 = detector.detectAndCompute(img2, None)
    
    matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    matches = matcher.match(des1, des2)
    matches = sorted(matches, key=lambda x: x.distance)
    
    result = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], None)
    
    cv2.imwrite('matches.jpg', result)
    cv2.waitKey()
    cv2.destroyAllWindows()

Optical Flow Analysis

import numpy as np
import cv2

if __name__ == '__main__':
    video = cv2.VideoCapture('ant_video.mp4')
    
    # ShiTomasi corner detection parameters
    feature_params = dict(
        maxCorners=100,
        qualityLevel=0.5,
        minDistance=30,
        blockSize=10
    )
    
    # Lucas-Kanade optical flow parameters
    lk_params = dict(
        winSize=(15, 15),
        maxLevel=2,
        criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)
    )
    
    ret, previous_frame = video.read()
    previous_gray = cv2.cvtColor(previous_frame, cv2.COLOR_BGR2GRAY)
    initial_points = cv2.goodFeaturesToTrack(previous_gray, mask=None, **feature_params)
    
    mask = np.zeros_like(previous_frame)
    colors = np.random.randint(0, 255, (100, 3))
    
    while True:
        ret, current_frame = video.read()
        if not ret:
            break
        
        current_gray = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
        
        new_points, status, _ = cv2.calcOpticalFlowPyrLK(
            previous_gray, current_gray, initial_points, None, **lk_params
        )
        
        good_new = new_points[status == 1]
        good_old = initial_points[status == 1]
        
        for idx, (new, old) in enumerate(zip(good_new, good_old)):
            x_new, y_new = new.ravel()
            x_old, y_old = old.ravel()
            x_new, y_new = int(x_new), int(y_new)
            x_old, y_old = int(x_old), int(y_old)
            
            mask = cv2.line(mask, (x_new, y_new), (x_old, y_old), 
                           colors[idx].tolist(), 2)
            current_frame = cv2.circle(current_frame, (x_new, y_new), 
                                      5, colors[idx].tolist(), -1)
        
        result = cv2.add(current_frame, mask)
        cv2.imshow('Optical Flow', result)
        
        if cv2.waitKey(30) & 0xff == 27:
            break
        
        previous_gray = current_gray.copy()
        initial_points = good_new.reshape(-1, 1, 2)
    
    cv2.destroyAllWindows()
    video.release()

Image Filtering (Box Filter)

import cv2 as cv

img = cv.imread("lena.png")
kernel_size = (5, 5)
filtered = cv.boxFilter(img, -1, ksize=kernel_size)

cv.imshow("Box Filter", filtered)
cv.waitKey(0)

Image Cutting and Pasting

import cv2
import numpy as np

if __name__ == '__main__':
    img = cv2.imread('football.jpg', cv2.IMREAD_COLOR)
    
    start_coords = [493, 594]
    end_coords = [112, 213]
    
    ball_region = img[start_coords[0]:start_coords[1], end_coords[0]:end_coords[1]]
    
    x_step = 101
    y_step = 10
    
    for offset in range(-1, 4):
        x_offset = x_step * offset
        y_offset = y_step * offset
        img[start_coords[0]-y_offset:start_coords[1]-y_offset,
            end_coords[0]+x_offset:end_coords[1]+x_offset] = ball_region
    
    cv2.imshow("Processed", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

PyTorch Tensor Operations

Creating and Manipulating Complex Tensors

import torch

# Create complex tensor from real and imaginary parts
real_part = torch.rand(2, 2)
imag_part = torch.rand(2, 2)
complex_tensor = torch.complex(real_part, imag_part)
print(complex_tensor)

# Reshape and view operations
a = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8])
print(a.reshape([4, 2]))

b = torch.FloatTensor([24, 56, 10, 20, 30, 40, 50, 1, 2, 3, 4, 5])
print(b.view(4, 3))

# Take operation
data = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
indices = torch.tensor([1, 4, 5])
result = torch.take(data, indices)

# Unbind operation
mat = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
layers = torch.unbind(mat)

# Reciprocal
x = torch.tensor([[1.6, 2.5], [3.0, 4.0], [5.0, 6.0]])
reciprocal_result = torch.reciprocal(x)

# Transpose
matrix = torch.tensor([[3, 8], [5, 6]])
transposed = torch.t(matrix)

# Concatenation
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5, 6]])
c = torch.cat((a, b), dim=0)

Jupyter Notebook Configuratoin

Setting Up Conda Environments in Jupyter

# Generate configuration file
jupyter notebook --generate-config

# Install ipykernel if needed
pip install ipykernel

# Add conda environment to Jupyter
python -m ipykernel install --user --name environment_name --display-name "Display Name"

# List all kernels
jupyter kernelspec list

# Remove a kernel
jupyter kernelspec remove kernel_name

Configuring Jupyter Nbextensions

# Uninstall existing nbextension packages
pip uninstall jupyter_contrib_nbextensions
pip uninstall jupyter_nbextensions_configurator

# Install from mirror
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com jupyter_contrib_nbextensions

# Run installation script from site-packages
python -m jupyter_contrib_nbextensions.application install --user

# Install configurator
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com jupyter_nbextensions_configurator
jupyter nbextensions_configurator enable --user

SQL Deduplication Patterns

-- Remove duplicates keeping latest record per group
SELECT id, name, age FROM users a 
WHERE id IN (
    SELECT MAX(id) FROM users GROUP BY age
);

-- Alternative using EXISTS
SELECT id, name, age FROM users a 
WHERE EXISTS (
    SELECT id FROM (
        SELECT MAX(id) as id FROM users GROUP BY age
    ) b WHERE a.id = b.id
);

Command Line Utilities

unzip Options Reference

# Common unzip options:
# -c: display output with character conversion
# -f: update existing files
# -l: list archive contents
# -p: display without conversion
# -t: test archive integrity
# -v: verbose mode
# -z: show archive comments
# -j: don't extract directory paths
# -L: lowercase all filenames
# -d: specify extraction directory
# -x: exclude specified files
# -q: quiet mode (no output)
# -o: overwrite without prompting

# Example: extract quietly to specific directory
unzip -q archive.zip -d /target/path

wget Download Options

# Download to current directory
wget https://example.com/file.rpm

# Specify download directory
wget -P /home/downloads https://example.com/file.rpm

# Specify directory and filename
wget https://example.com/file.rpm -O /home/downloads/renamed.rpm

Object Tracking Framework

import numpy as np

class ObjectTracker:
    def __init__(self, max_age=1, min_hits=3, iou_threshold=0.3):
        self.max_age = max_age
        self.min_hits = min_hits
        self.iou_threshold = iou_threshold
        self.tracked_objects = []
        self.frame_counter = 0
    
    def update(self, detections=np.empty((0, 5))):
        self.frame_counter += 1
        
        predicted = np.zeros((len(self.tracked_objects), 5))
        to_remove = []
        
        for idx, obj in enumerate(predicted):
            position = self.tracked_objects[idx].predict()[0]
            predicted[idx] = [position[0], position[1], position[2], position[3], 0]
            if np.any(np.isnan(position)):
                to_remove.append(idx)
        
        predicted = np.ma.compress_rows(np.ma.masked_invalid(predicted))
        
        for idx in reversed(to_remove):
            self.tracked_objects.pop(idx)
        
        matched, unmatched_det, unmatched_track = self.match_detections(
            detections, predicted, self.iou_threshold
        )
        
        for match in matched:
            self.tracked_objects[match[1]].update(detections[match[0], :])
        
        for det_idx in unmatched_det:
            self.tracked_objects.append(KalmanBoxTracker(detections[det_idx, :]))
        
        results = []
        obj_count = len(self.tracked_objects)
        
        for obj in reversed(self.tracked_objects):
            state = obj.get_state()[0]
            if (obj.time_since_update <= self.max_age and 
                obj.hit_streak >= self.min_hits or 
                self.frame_counter <= self.min_hits):
                results.append(np.concatenate((state, [obj.id + 1])).reshape(1, -1))
            obj_count -= 1
            
            if obj.time_since_update > self.max_age:
                self.tracked_objects.pop(obj_count)
        
        if results:
            return np.concatenate(results)
        return np.empty((0, 5))
    
    def match_detections(self, detections, predictions, threshold):
        # IOU matching implementation
        matched = []
        unmatched_detections = list(range(len(detections)))
        unmatched_tracks = list(range(len(predictions)))
        return matched, unmatched_detections, unmatched_tracks

class KalmanBoxTracker:
    def __init__(self, detection):
        self.id = 0
        self.time_since_update = 0
        self.hit_streak = 0
    
    def predict(self):
        return [[0, 0, 0, 0]]
    
    def update(self, detection):
        self.time_since_update = 0
        self.hit_streak += 1
    
    def get_state(self):
        return [[0, 0, 0, 0]]

Color Space Reference

RGB: Red-Green-Blue, hardware-oriented color space unsuitable for image processing tasks requiring perceptual uniformity.

CMY/CMYK: Cyan-Magenta-Yellow used in printing, inverse of RGB based on light reflection.

HSV: Hue-Saturation-Value, perceptually intuitive for color adjustments. Hue represents color type, saturation represents purity, value represents brightness.

HLS: Similar to HSV with Lightness component instead of Value. L=100 is white, L=0 is black.

YUV/YCbCr: Luminance-Chrominance separation. Y is brightness, Cb/Cr represent blue/red chroma differences.

Lab: Device-independent color model with L for lightness (0-100) and a/b for chromatic components (-128 to 127).

LUV: Uniform color space designed for visual consistency with L for lightness and u/v for chromaticity coordinates.

import matplotlib.pyplot as plt
import cv2

def convert_and_display(image_path):
    bgr_img = cv2.imread(image_path)
    
    conversions = {
        'BGR': bgr_img,
        'RGB': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2RGB),
        'GRAY': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY),
        'YCrCb': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2YCrCb),
        'HSV': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2HSV),
        'HLS': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2HLS),
        'Lab': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2Lab),
        'Luv': cv2.cvtColor(bgr_img, cv2.COLOR_BGR2Luv)
    }
    
    for idx, (name, img) in enumerate(conversions.items()):
        plt.subplot(3, 3, idx + 1)
        plt.imshow(img[:, :, ::-1] if len(img.shape) == 3 else img, 'gray')
        plt.title(name)
        plt.axis('off')
    
    plt.show()

Flash Attention Installation Notes

For environments with torch 2.2 and CUDA 12.1, use the following wheel without cxx11 ABI:

# Download from releases with cxx11abiFALSE tag
# flash_attn-2.5.6+cu122torch2.2cxx11abiFALSE-cp310-cp310-linux_x86_64.whl

# If encountering undefined symbol errors, use:
# Try cxx11abiFALSE version

Current GPU environment verification:

import torch
torch.backends.cudnn.benchmark = True
print(torch.cuda.is_available())  # False
print(torch.cuda.device_count())   # 0
print(torch.__version__)          # 2.2.1+cu121
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)                     # cpu
print(torch.version.cuda)          # 12.1

LLM Pattern Recognition Observations

Large language models demonstrate strong performance in discrete sequence prediction tasks, including non-textual pattern recognition like IQ test questions. However, they struggle with reverse sequence output tasks—even short sequences of 10-20 elements frequently contain errors. This limitation arises from the autoregressive decoding process, where output probability distributions favor grammatically consistent text over exact reversals.

When digits are treated as arbitrary symbols rather than numeric values, models maintain higher accuracy in sequence prediction tasks.

Tags: OpenCV pytorch dowhy causal-inference media-pipe

Posted on Wed, 08 Jul 2026 17:27:02 +0000 by abbe-rocks