🐍 کتابخانه مرجع پایتون

👁️ مبانی OpenCV

OpenCV (Open Source Computer Vision Library) یکی از محبوب‌ترین کتابخانه‌های متن‌باز برای بینایی کامپیوتر و پردازش تصویر است. این کتابخانه شامل بیش از ۲۵۰۰ الگوریتم بهینه‌شده برای پردازش تصاویر، تشخیص اشیا، تشخیص چهره، پردازش ویدیو و ... می‌باشد . OpenCV با زبان‌های C++، Python و Java کار می‌کند و برای پروژه‌های علمی، صنعتی و تحقیقاتی بسیار محبوب است .

پیش‌نیاز: آشنایی با Python و مفاهیم پایه پردازش تصویر (اختیاری).

🔹 نصب و import

# نصب (در محیط واقعی)
# pip install opencv-python
# pip install opencv-contrib-python

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

print(f"OpenCV version: {cv2.__version__}")
print("OpenCV imported successfully!")

🔹 خواندن و نمایش تصویر

import cv2
import matplotlib.pyplot as plt

# ===== خواندن تصویر =====
# ایجاد یک تصویر نمونه (ماتریس 200x200 با رنگ آبی)
image = np.zeros((200, 200, 3), dtype=np.uint8)
image[:, :] = [255, 0, 0]  # BGR (آبی)

# ===== ذخیره تصویر =====
cv2.imwrite('sample_image.jpg', image)
print("Sample image saved as 'sample_image.jpg'")

# ===== نمایش تصویر با matplotlib =====
# OpenCV تصاویر را به صورت BGR می‌خواند، matplotlib RGB می‌خواهد
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(4, 4))
plt.imshow(image_rgb)
plt.title("Sample Image")
plt.axis('off')
plt.show()

# ===== خواندن تصویر از فایل =====
# img = cv2.imread('path/to/image.jpg')
# if img is None:
#     print("Error: Could not load image")
# else:
#     cv2.imshow('Window Title', img)
#     cv2.waitKey(0)
#     cv2.destroyAllWindows()

🔹 تغییر اندازه تصویر

import cv2
import matplotlib.pyplot as plt

# ===== ایجاد تصویر نمونه =====
image = np.random.randint(0, 255, (300, 400, 3), dtype=np.uint8)

# ===== تغییر اندازه =====
# روش ۱: تعیین اندازه دقیق
resized_1 = cv2.resize(image, (200, 150))  # (width, height)

# روش ۲: تعیین ضریب مقیاس
resized_2 = cv2.resize(image, None, fx=0.5, fy=0.5)  # 50% کوچک‌تر

# ===== نمایش نتیجه =====
plt.figure(figsize=(12, 4))

plt.subplot(1, 3, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title(f"Original: {image.shape[1]}x{image.shape[0]}")
plt.axis('off')

plt.subplot(1, 3, 2)
plt.imshow(cv2.cvtColor(resized_1, cv2.COLOR_BGR2RGB))
plt.title(f"Resized: 200x150")
plt.axis('off')

plt.subplot(1, 3, 3)
plt.imshow(cv2.cvtColor(resized_2, cv2.COLOR_BGR2RGB))
plt.title(f"Resized: 50%")
plt.axis('off')

plt.tight_layout()
plt.show()

print(f"Original shape: {image.shape}")
print(f"Resized 1 shape: {resized_1.shape}")
print(f"Resized 2 shape: {resized_2.shape}")

🔹 تبدیل به خاکستری و تغییر رنگ

import cv2
import matplotlib.pyplot as plt

# ===== ایجاد تصویر رنگی =====
image = np.zeros((200, 200, 3), dtype=np.uint8)
image[:, :100] = [0, 0, 255]    # قرمز (BGR)
image[:, 100:] = [255, 0, 0]    # آبی

# ===== تبدیل به خاکستری =====
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# ===== تغییر فضای رنگی =====
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)

# ===== نمایش =====
plt.figure(figsize=(12, 4))

plt.subplot(1, 4, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title("Original (BGR)")
plt.axis('off')

plt.subplot(1, 4, 2)
plt.imshow(gray, cmap='gray')
plt.title("Grayscale")
plt.axis('off')

plt.subplot(1, 4, 3)
plt.imshow(cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB))
plt.title("HSV")
plt.axis('off')

plt.subplot(1, 4, 4)
plt.imshow(cv2.cvtColor(lab, cv2.COLOR_LAB2RGB))
plt.title("LAB")
plt.axis('off')

plt.tight_layout()
plt.show()

🔹 فیلترها و Blur

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

# ===== ایجاد تصویر با نویز =====
image = np.zeros((200, 200), dtype=np.uint8)
cv2.rectangle(image, (50, 50), (150, 150), 255, -1)
noise = np.random.randint(0, 50, image.shape, dtype=np.uint8)
image_noisy = cv2.add(image, noise)

# ===== اعمال فیلترهای مختلف =====
# ۱. Gaussian Blur
gaussian = cv2.GaussianBlur(image_noisy, (5, 5), 0)

# ۲. Median Blur (برای حذف نویز فلفل نمکی)
median = cv2.medianBlur(image_noisy, 5)

# ۳. Bilateral Filter (حفظ لبه‌ها)
bilateral = cv2.bilateralFilter(image_noisy, 9, 75, 75)

# ===== نمایش =====
plt.figure(figsize=(12, 4))

plt.subplot(1, 4, 1)
plt.imshow(image_noisy, cmap='gray')
plt.title("Noisy Image")
plt.axis('off')

plt.subplot(1, 4, 2)
plt.imshow(gaussian, cmap='gray')
plt.title("Gaussian Blur")
plt.axis('off')

plt.subplot(1, 4, 3)
plt.imshow(median, cmap='gray')
plt.title("Median Blur")
plt.axis('off')

plt.subplot(1, 4, 4)
plt.imshow(bilateral, cmap='gray')
plt.title("Bilateral Filter")
plt.axis('off')

plt.tight_layout()
plt.show()

🔹 تشخیص لبه (Edge Detection)

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

# ===== ایجاد تصویر با اشکال هندسی =====
image = np.zeros((300, 300), dtype=np.uint8)
cv2.rectangle(image, (50, 50), (250, 250), 255, 2)
cv2.circle(image, (150, 150), 80, 255, 2)

# ===== تشخیص لبه با Canny =====
edges = cv2.Canny(image, 50, 150)

# ===== تشخیص لبه با Sobel =====
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
sobel = cv2.magnitude(sobel_x, sobel_y)
sobel = np.uint8(np.clip(sobel, 0, 255))

# ===== تشخیص لبه با Laplacian =====
laplacian = cv2.Laplacian(image, cv2.CV_64F)
laplacian = np.uint8(np.clip(laplacian, 0, 255))

# ===== نمایش =====
plt.figure(figsize=(12, 4))

plt.subplot(1, 4, 1)
plt.imshow(image, cmap='gray')
plt.title("Original")
plt.axis('off')

plt.subplot(1, 4, 2)
plt.imshow(edges, cmap='gray')
plt.title("Canny Edge")
plt.axis('off')

plt.subplot(1, 4, 3)
plt.imshow(sobel, cmap='gray')
plt.title("Sobel")
plt.axis('off')

plt.subplot(1, 4, 4)
plt.imshow(laplacian, cmap='gray')
plt.title("Laplacian")
plt.axis('off')

plt.tight_layout()
plt.show()

🔹 تشخیص چهره با Haar Cascade

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

# ===== بارگذاری Haar Cascade برای تشخیص چهره =====
# در سیستم واقعی، مسیر فایل cascade را مشخص کنید
# face_cascade = cv2.CascadeClassifier(
#     cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
# )

# ===== ایجاد تصویر نمونه با یک چهره ساده (دایره) =====
image = np.zeros((300, 300, 3), dtype=np.uint8)
cv2.circle(image, (150, 150), 80, (255, 255, 255), -1)  # صورت
cv2.circle(image, (110, 120), 15, (0, 0, 0), -1)        # چشم چپ
cv2.circle(image, (190, 120), 15, (0, 0, 0), -1)        # چشم راست
cv2.ellipse(image, (150, 180), (30, 15), 0, 0, 180, (0, 0, 0), -1)  # دهان

# ===== تشخیص چهره (با روش دایره‌ای ساده) =====
# این یک روش ساده برای نمایش است، در عمل از Haar Cascade استفاده کنید
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# ===== تشخیص با Hough Circle =====
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20,
                          param1=50, param2=30, minRadius=60, maxRadius=100)

# ===== رسم دور چهره =====
result = image.copy()
if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        cv2.circle(result, (i[0], i[1]), i[2], (0, 255, 0), 3)

plt.figure(figsize=(8, 4))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title("Original")
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.title("Face Detection")
plt.axis('off')
plt.tight_layout()
plt.show()

print("Note: For real face detection, use Haar Cascade or DNN models.")

🔹 دوربین و پردازش ویدیو

import cv2
import numpy as np

# ===== ضبط ویدیو از دوربین (نمونه کد برای اجرا در محیط واقعی) =====
"""
cap = cv2.VideoCapture(0)  # 0 برای دوربین پیش‌فرض

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # تبدیل به خاکستری
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # نمایش
    cv2.imshow('Video', frame)
    cv2.imshow('Gray', gray)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
"""

# ===== خواندن و پردازش یک ویدیو =====
# ===== ایجاد یک ویدیوی نمونه (تصاویر متوالی) =====
frames = []
for i in range(30):
    frame = np.zeros((200, 200, 3), dtype=np.uint8)
    cv2.circle(frame, (100 + i*2, 100), 30, (0, 0, 255), -1)
    frames.append(frame)

# ===== ذخیره ویدیو =====
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 10.0, (200, 200))

for frame in frames:
    out.write(frame)

out.release()
print("Video saved as 'output.avi'")

# ===== نمایش ویدیو در notebook =====
print("Video created with 30 frames of a moving circle.")

🔹 تشخیص اشیا با Template Matching

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

# ===== ایجاد تصویر اصلی و الگو =====
image = np.zeros((200, 200), dtype=np.uint8)
cv2.rectangle(image, (50, 50), (150, 150), 255, -1)
cv2.circle(image, (100, 100), 30, 0, -1)

# ===== الگو (قسمتی از تصویر اصلی) =====
template = image[70:130, 70:130]  # بخشی از تصویر

# ===== Template Matching =====
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 
           'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 
           'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

# ===== نمایش =====
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(image, cmap='gray')
plt.title("Image")
plt.axis('off')

plt.subplot(1, 3, 2)
plt.imshow(template, cmap='gray')
plt.title("Template")
plt.axis('off')

# ===== اجرای Template Matching =====
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

# پیدا کردن موقعیت
top_left = max_loc
h, w = template.shape
bottom_right = (top_left[0] + w, top_left[1] + h)

# ===== رسم نتیجه =====
image_color = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
cv2.rectangle(image_color, top_left, bottom_right, (0, 255, 0), 2)

plt.subplot(1, 3, 3)
plt.imshow(cv2.cvtColor(image_color, cv2.COLOR_BGR2RGB))
plt.title("Detection Result")
plt.axis('off')

plt.tight_layout()
plt.show()
print(f"Template found at position: {top_left}")

🔹 مثال جامع: تشخیص شکل‌ها

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

def detect_shapes(image):
    """
    تشخیص اشکال هندسی در تصویر
    """
    # تبدیل به خاکستری
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # تشخیص لبه‌ها
    edges = cv2.Canny(gray, 50, 150)
    
    # پیدا کردن کانتورها
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    result = image.copy()
    shape_names = []
    
    for contour in contours:
        # تقریب کانتور
        epsilon = 0.04 * cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, epsilon, True)
        
        # تعداد اضلاع
        sides = len(approx)
        
        # تشخیص شکل
        if sides == 3:
            shape = "Triangle"
        elif sides == 4:
            # بررسی مربع یا مستطیل
            x, y, w, h = cv2.boundingRect(approx)
            aspect_ratio = w / h
            if 0.95 <= aspect_ratio <= 1.05:
                shape = "Square"
            else:
                shape = "Rectangle"
        elif sides == 5:
            shape = "Pentagon"
        elif sides == 6:
            shape = "Hexagon"
        else:
            # تشخیص دایره
            area = cv2.contourArea(contour)
            perimeter = cv2.arcLength(contour, True)
            if perimeter > 0:
                circularity = 4 * np.pi * area / (perimeter * perimeter)
                if circularity > 0.8:
                    shape = "Circle"
                else:
                    shape = "Unknown"
            else:
                shape = "Unknown"
        
        # رسم کانتور و نام
        cv2.drawContours(result, [contour], -1, (0, 255, 0), 2)
        
        # محاسبه مرکز
        M = cv2.moments(contour)
        if M['m00'] != 0:
            cx = int(M['m10'] / M['m00'])
            cy = int(M['m01'] / M['m00'])
            cv2.putText(result, shape, (cx-30, cy), 
                       cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
        
        shape_names.append(shape)
    
    return result, shape_names

# ===== ایجاد تصویر با اشکال مختلف =====
image = np.zeros((300, 400, 3), dtype=np.uint8)

# رسم اشکال
cv2.rectangle(image, (20, 20), (100, 100), (255, 255, 255), -1)  # مربع
cv2.circle(image, (200, 60), 40, (255, 255, 255), -1)            # دایره
cv2.rectangle(image, (300, 20), (380, 90), (255, 255, 255), -1)  # مستطیل

pts = np.array([[20, 150], [60, 200], [20, 250], [80, 250], [60, 200]], np.int32)
cv2.polylines(image, [pts], True, (255, 255, 255), -1)           # پنج‌ضلعی

pts2 = np.array([[200, 150], [240, 130], [280, 150], 
                 [280, 200], [240, 220], [200, 200]], np.int32)
cv2.polylines(image, [pts2], True, (255, 255, 255), -1)          # شش‌ضلعی

pts3 = np.array([[330, 140], [360, 170], [350, 210], 
                 [310, 210], [300, 170]], np.int32)
cv2.polylines(image, [pts3], True, (255, 255, 255), -1)          # مثلث

# ===== اجرای تشخیص =====
result, shapes = detect_shapes(image)

print("Detected shapes:", shapes)

# ===== نمایش =====
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title("Original")
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.title("Shape Detection")
plt.axis('off')

plt.tight_layout()
plt.show()

📌 نکات کلیدی

← قبلی: NLP با NLTK → بعدی: API با Flask ↑ بازگشت به فهرست پیشرفته