👁️ مبانی 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()
📌 نکات کلیدی
- ✅ OpenCV تصاویر را به صورت BGR (آبی-سبز-قرمز) میخواند، در حالی که matplotlib از RGB استفاده میکند.
- ✅ توابع `cv2.imread()` و `cv2.imwrite()` برای خواندن و ذخیره تصاویر استفاده میشوند.
- ✅ `cv2.resize()` برای تغییر اندازه تصاویر استفاده میشود.
- ✅ `cv2.cvtColor()` برای تبدیل بین فضاهای رنگی مختلف (BGR، HSV، LAB، GRAY) استفاده میشود.
- ✅ فیلترهای Gaussian Blur، Median Blur و Bilateral Filter برای کاهش نویز و صافسازی تصاویر استفاده میشوند.
- ✅ الگوریتم Canny یکی از بهترین روشها برای تشخیص لبه است.
- ✅ Haar Cascade یک روش کلاسیک برای تشخیص چهره و اشیاء است.
- ✅ Contour Detection برای تشخیص و تحلیل اشکال هندسی در تصاویر استفاده میشود.
- ✅ OpenCV از پردازش ویدیو و دوربین با `cv2.VideoCapture()` پشتیبانی میکند.