عالیه! بیایید از صفرِ صفر شروع کنیم و一步一步 با هم کدنویسی کنیم. قول میدم هیچ مفهومی رو بدون توضیح ول نمیکنیم.
---
جلسه اول: "آرایه چیه و چرا عکس یک آرایهست؟"
۱. اولین برخورد: آرایه رو لمس کن
بیا اولین کدها رو بزنیم ببینیم اصلاً NumPy چی به ما میده:
```python
import numpy as np
# سادهترین آرایه ممکن: یه لیست معمولی رو تبدیل به آرایه NumPy میکنیم
my_list = [1, 2, 3, 4, 5]
my_array = np.array(my_list)
print("لیست پایتونی:", my_list)
print("آرایه NumPy:", my_array)
print("نوع آرایه:", type(my_array))
```

چی شد؟
یه لیست معمولی رو دادیم به np.array() و اون بهمون یه شیء جدید برگردوند. این شیء جدید یه موجود ریاضیایه، نه یه لیست ساده.
---
۲. فرق آرایه با لیست: چرا NumPy؟
```python
import numpy as np
# بیایید مقایسه کنیم
python_list = [1, 2, 3, 4, 5]
numpy_array = np.array([1, 2, 3, 4, 5])
# عملیات ریاضی روی لیست:

try:
result = python_list * 2
print("لیست × ۲:", result) # [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] !!! تکرار میشه!
except:
print("نمیشه عملیات ریاضی واقعی انجام داد")
# عملیات ریاضی روی آرایه:

result = numpy_array * 2
print("آرایه × ۲:", result) # [2 4 6 8 10] !!! عملیات ریاضی واقعی
```
نکته حیاتی:
· لیست * 2 میشه تکرار لیست
· آرایه * 2 میشه ضرب ریاضی
---
۳. حالا عکس چیه؟ یه آرایه ۲ بعدی
بیایید یه "عکس" ساده ۳×۳ پیکسل بسازیم:
```python
import numpy as np
# یه عکس ۳×۳ که فقط اعداد روشنایی داره (عکس خاکستری)
# هر عدد نشوندهنده روشنایی اون پیکسله: ۰=سیاه، ۲۵۵=سفید
image = np.array([
[0, 128, 255], # سطر اول: سیاه، خاکستری، سفید
[50, 100, 200], # سطر دوم
[255, 0, 128] # سطر سوم
])
print("عکس ۳×۳ ما:")
print(image)
print("\nشکل عکس:", image.shape) # (3, 3) یعنی ۳ سطر، ۳ ستون
print("نوع داده:", image.dtype) # int64 یعنی اعداد صحیح
```
عکس واقعی = آرایه NumPy
وقتی با OpenCV عکس میخونی، دقیقاً همین ساختار رو داری، فقط بزرگتر:
· یه عکس ۱۰۰×۱۰۰ = آرایه NumPy با شکل (100, 100)
· یه عکس رنگی = آرایه NumPy با شکل (100, 100, 3) ← سه تا عدد برای هر پیکسل: آبی، سبز، قرمز
---
۴. بریم OpenCV رو لمس کنیم: اولین عکس واقعی
```python
import cv2
import numpy as np
# یه عکس ساده ۳۰۰×۳۰۰ با NumPy بسازیم (بدون دوربین)
print("=== ساختن یه عکس ساده با NumPy ===")
# آرایه ۳۰۰×۳۰۰ پر از صفر = عکس کاملاً سیاه
black_image = np.zeros((300, 300), dtype=np.uint8)
print("شکل عکس سیاه:", black_image.shape) # (300, 300)
print("مقدار یه پیکسل:", black_image[0, 0]) # 0
# حالا بیایید یه مستطیل سفید وسطش بکشیم
# با برش NumPy: سطرهای ۱۰۰ تا ۲۰۰ و ستونهای ۱۰۰ تا ۲۰۰
black_image[100:200, 100:200] = 255 # سفید کن
# نمایش با OpenCV
cv2.imshow("عکس ساخته شده با NumPy", black_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
اینجا چی شد؟
· np.zeros((300, 300)) یه آرایه ۳۰۰×۳۰۰ پر از صفر ساخت (عکس سیاه)
· black_image[100:200, 100:200] = 255 با برش NumPy، یه مربع رو سفید کردیم
· OpenCV بدون هیچ زحمتی این آرایه رو به عنوان عکس نشون داد
---
۵. بیایید با ماتریسها بازی کنیم (مثل عکس واقعی)
```python
import numpy as np
# یه عکس نمونه ۴×۴
sample = np.array([
[10, 20, 30, 40],
[50, 60, 70, 80],
[90, 100, 110, 120],
[130, 140, 150, 160]
])
print("عکس کامل:\n", sample)
# ۱. برش ساده: ۲ سطر اول، ۳ ستون اول
print("\n۱. برش [0:2, 0:3]:\n", sample[0:2, 0:3])
# یعنی از سطر ۰ تا ۱ (خود ۲ شامل نمیشه)، ستون ۰ تا ۲
# ۲. انتخاب یک ستون کامل
print("\n۲. ستون دوم (index=1):\n", sample[:, 1])
# یعنی تمام سطرها `:`، ستون شماره ۱
# ۳. انتخاب یه ناحیه از وسط
print("\n۳. وسط تصویر:\n", sample[1:3, 1:3])
# سطرهای ۱ و ۲، ستونهای ۱ و ۲
```
این دقیقاً کاریه که توی پردازش تصویر میکنی:
· میگی "از عکس، فقط ناحیه صورت رو برش بده"
· میگی "ستون وسط عکس رو نشون بده"
---
۶. عملگرهای مقایسهای: ماسک بولین (جادوی اصلی)
این بخش خیلی مهمه! این همون چیزیه که توی تشخیص سون سگمنت استفاده کردیم:
```python
import numpy as np
# عکس ساده ۳×۳
image = np.array([
[10, 150, 250],
[50, 200, 30],
[100, 80, 255]
])
print("عکس اصلی:\n", image)
# ۱. ماسک: کدوم پیکسلها روشنتر از ۱۰۰ هستند؟
mask = image > 100
print("\n۱. ماسک (image > 100):\n", mask)
# True یعنی روشنتر از ۱۰۰، False یعنی تاریکتر
# ۲. از ماسک استفاده کنیم: فقط پیکسلهای روشن رو نشون بده
bright_pixels = image[mask]
print("\n۲. فقط پیکسلهای روشنتر از ۱۰۰:\n", bright_pixels)
# ۳. تعداد پیکسلهای روشن
count_bright = np.sum(mask)
print("\n۳. تعداد پیکسلهای روشن:", count_bright)
# ۴. مختصات پیکسلهای روشن
coordinates = np.where(mask)
print("\n۴. مختصات (سطر, ستون):", coordinates)
print(" یعنی پیکسلهای روشن در این موقعیتها هستند:",
list(zip(coordinates[0], coordinates[1])))
```
این مغز خیلی از الگوریتمهای پردازش تصویر:
· ماسک بساز (پیکسلهای روشن، پیکسلهای قرمز، ...)
· با اون ماسک کار انجام بده (بشمار، تغییر بده، پیدا کن)
---
۷. جمعبندی: حالا عکس سون سگمنت رو ساده میفهمی
```python
import cv2
import numpy as np
# فرض کن این تابع یه سگمنت از نمایشگر رو چک میکنه
def check_segment(segment_image):
"""
segment_image: یه برش NumPy از عکس اصلی که فقط یه سگمنت رو نشون میده
"""
# میپرسیم: چندتا پیکسل روشن (بیشتر از ۲۰۰) داریم؟
bright_pixels = np.sum(segment_image > 200)
total_pixels = segment_image.size # تعداد کل پیکسلها
ratio = bright_pixels / total_pixels
print(f" پیکسلهای روشن: {bright_pixels}/{total_pixels} = {ratio:.2f}")
return ratio > 0.5 # اگه بیش از نصفش روشنه، یعنی سگمنت فعاله
# === تست با یه عکس ساختگی ===
print("=== تست تشخیص سگمنت ===")
# یه سگمنت "روشن" (خیلی از پیکسلها سفیدن)
segment_on = np.array([
[200, 255, 240, 255],
[250, 240, 255, 230],
[200, 255, 250, 240]
])
print("\nسگمنت روشن:")
result = check_segment(segment_on)
print(" نتیجه: سگمنت", "فعال

" if result else "غیرفعال

")
# یه سگمنت "خاموش" (اکثر پیکسلها سیاهن)
segment_off = np.array([
[10, 15, 20, 5],
[30, 10, 25, 15],
[20, 5, 10, 25]
])
print("\nسگمنت خاموش:")
result = check_segment(segment_off)
print(" نتیجه: سگمنت", "فعال

" if result else "غیرفعال

")
```
---
تمرینهای هفته (از ساده به سخت)
تمرین ۱ (آسون): برش و تغییر
```python
# یه آرایه ۵×۵ از اعداد ۱ تا ۲۵ بساز
# بعد، مربع ۳×۳ وسطش رو به ۹۹ تغییر بده
arr = np.arange(1, 26).reshape(5, 5)
print("اصلی:\n", arr)
# راهنمایی: مربع وسط از سطر ۱ تا ۴ و ستون ۱ تا ۴ هست
# کدت رو اینجا بنویس:
```
تمرین ۲ (متوسط): ماسک و آستانهگیری
```python
# یه عکس ۴×۴ با اعداد تصادفی بین ۰ تا ۲۵۵ بساز
# تمام پیکسلهای بالای ۱۲۸ رو به ۲۵۵ و زیرش رو به ۰ تبدیل کن (بدون حلقه!)
np.random.seed(42)
image = np.random.randint(0, 256, size=(4, 4))
print("اصلی:\n", image)
# کدت رو اینجا بنویس (راهنمایی: از ماسک و ایندکسگذاری بولین استفاده کن)
```
تمرین ۳ (واقعی): با دوربین/وبکم تست کن
```python
import cv2
import numpy as np
# برنامهای بنویس که:
# ۱. وبکم رو باز کنه
# ۲. تصویر رو خاکستری کنه
# ۳. فقط پیکسلهای خیلی روشن (بالای ۲۰۰) رو سفید و بقیه رو سیاه کنه
# ۴. نشون بده
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# تبدیل به خاکستری
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# اینجا با NumPy ماسک بزن و فقط نورهای قوی رو نگه دار
# کد NumPy خودت رو اینجا بنویس:
result = gray.copy()
# result = ???
cv2.imshow("Original", gray)
cv2.imshow("Only Bright", result)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
```
---
چی یاد گرفتیم؟
۱. آرایه NumPy = ماتریس اعداد (و عکس هم یه ماتریسه)
۲. برش آرایه = انتخاب ناحیه از عکس
۳. ماسک بولین = پیدا کردن پیکسلهای خاص
۴. np.sum, np.mean, np.where = ابزارهای تحلیل عکس
سوال بعدیت چیه؟ میتونیم بریم سراغ یه پروژه واقعیتر (مثل تشخیص عدد با سون سگمنت واقعی) یا بیشتر روی مفاهیم NumPy عمیق بشیم.