کار با opencv در گوشی

saalek110

Well-Known Member
برنامه گرفتن ۴ عکس با فاصله چند ثانیه و ذخیره کردن در پوشه ای در پوشه دانلود:

Python:
import cv2
import numpy as np
import time
import os
from datetime import datetime

print("=" * 60)
print(" برنامه عکس‌برداری زمان‌دار با دوربین تبلت")
print("=" * 60)
print("ویژگی‌ها:")
print("• گرفتن ۴ عکس با فاصله ۵ ثانیه")
print("• نمایش ۴ عکس کنار هم")
print("• ذخیره خودکار عکس‌ها")
print("=" * 60)

# تنظیمات
NUM_PHOTOS = 4
DELAY_SECONDS = 5
PHOTO_WIDTH = 320
PHOTO_HEIGHT = 240

# استفاده از پوشه Download که دسترسی آسان‌تر دارد
save_folder = "/storage/emulated/0/Download/PhotoGrid/"
try:
    os.makedirs(save_folder, exist_ok=True)
    print(f" عکس‌ها در این پوشه ذخیره می‌شوند: {save_folder}")
except:
    # اگر نشد، از پوشه فعلی برنامه استفاده کن
    save_folder = "./PhotoGrid/"
    os.makedirs(save_folder, exist_ok=True)
    print(f" عکس‌ها در این پوشه ذخیره می‌شوند: {save_folder}")

# راه‌اندازی دوربین
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("❌ خطا: نمی‌تواند به دوربین دسترسی پیدا کند")
    exit()

# تنظیم رزولوشن دوربین
cap.set(cv2.CAP_PROP_FRAME_WIDTH, PHOTO_WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, PHOTO_HEIGHT)

print(f"✅ دوربین فعال شد - رزولوشن: {PHOTO_WIDTH}x{PHOTO_HEIGHT}")
print(f"⏱️  گرفتن {NUM_PHOTOS} عکس با فاصله {DELAY_SECONDS} ثانیه...\n")

# لیست برای ذخیره عکس‌ها
photos = []
photo_times = []
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

# گرفتن عکس‌ها
for i in range(NUM_PHOTOS):
    print(f"\n عکس {i+1} از {NUM_PHOTOS}:")
    
    # شمارش معکوس
    countdown_str = ""
    for countdown in range(DELAY_SECONDS, 0, -1):
        countdown_str += f"{countdown}... "
        print(f"{countdown}...", end=' ', flush=True)
        time.sleep(1)
    print("عکس!\n")
    
    # گرفتن عکس
    ret, frame = cap.read()
    
    if not ret:
        print(f"❌ خطا در گرفتن عکس {i+1}")
        # اضافه کردن تصویر سیاه به جای عکس خطا
        black_frame = np.zeros((PHOTO_HEIGHT, PHOTO_WIDTH, 3), dtype=np.uint8)
        cv2.putText(black_frame, 'ERROR', (50, 120),
                   cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        frame = black_frame
    
    # ذخیره عکس اصلی
    photo_time = datetime.now().strftime("%H%M%S")
    filename = f"{save_folder}photo_{i+1}_{photo_time}.jpg"
    
    try:
        cv2.imwrite(filename, frame)
        saved = True
    except:
        # اگر ذخیره نشد، فقط در حافظه نگه دار
        filename = f"photo_{i+1}_{photo_time}.jpg"
        saved = False
    
    # اضافه کردن متن زمان و شماره عکس روی تصویر
    annotated_frame = frame.copy()
    cv2.putText(annotated_frame, f'Photo {i+1}', (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    cv2.putText(annotated_frame, f'Time: {photo_time}', (10, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
    
    photos.append(annotated_frame)
    photo_times.append(photo_time)
    
    status_msg = "✅ ذخیره شد" if saved else "⚠️ فقط در حافظه"
    print(f"   {status_msg}: {filename}")

# آزاد کردن دوربین
cap.release()
print("\n" + "="*50)
print(f"✅ تمام {NUM_PHOTOS} عکس گرفته شدند")
print("="*50)

# ایجاد تصویر ترکیبی (گرید)
if len(photos) > 0:
    print("\n در حال ایجاد تصویر ترکیبی...")
    
    # اگر تعداد عکس‌ها کمتر از ۴ بود، با تصاویر سیاه پر کن
    while len(photos) < 4:
        black_img = np.zeros((PHOTO_HEIGHT, PHOTO_WIDTH, 3), dtype=np.uint8)
        cv2.putText(black_img, 'No Photo', (50, 120),
                   cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
        photos.append(black_img)
        photo_times.append("------")
    
    # ایجاد گرید ۲×۲
    # ردیف اول: عکس ۱ و ۲
    row1 = np.hstack((photos[0], photos[1]))
    # ردیف دوم: عکس ۳ و ۴
    row2 = np.hstack((photos[2], photos[3]))
    # ترکیب ردیف‌ها
    photo_grid = np.vstack((row1, row2))
    
    # اضافه کردن عنوان
    grid_with_title = cv2.copyMakeBorder(photo_grid, 50, 20, 20, 20, cv2.BORDER_CONSTANT, value=[40, 40, 40])
    cv2.putText(grid_with_title, f'Photo Grid - {timestamp}', (20, 35),
                cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2)
    
    # ذخیره تصویر ترکیبی
    grid_filename = f"{save_folder}photo_grid_{timestamp}.jpg"
    
    try:
        cv2.imwrite(grid_filename, grid_with_title)
        print(f"✅ تصویر ترکیبی ایجاد و ذخیره شد: {grid_filename}")
    except Exception as e:
        print(f"⚠️ تصویر ترکیبی ذخیره نشد: {e}")
        grid_filename = "در حافظه (ذخیره نشد)"
    
    # نمایش اطلاعات در ترمینال
    print("\n" + "="*60)
    print(" گزارش عکس‌برداری:")
    print("="*60)
    print(f"تاریخ: {datetime.now().strftime('%Y/%m/%d')}")
    print(f"زمان شروع: {timestamp}")
    print(f"تعداد عکس: {NUM_PHOTOS}")
    print(f"فاصله زمانی: {DELAY_SECONDS} ثانیه")
    
    print(f"\n جزئیات عکس‌ها:")
    for i in range(len(photos[:NUM_PHOTOS])):
        print(f"  عکس {i+1}: زمان {photo_times[i]}")
    
    print(f"\n پوشه ذخیره: {save_folder}")
    print(f"️  تصویر ترکیبی: photo_grid_{timestamp}.jpg")
    print("="*60)
    
    # نمایش گرید به صورت ASCII در ترمینال
    print("\n پیش‌نمایش گرید (مقیاس کوچک):")
    print("┌" + "─"*64 + "┐")
    
    # ایجاد نسخه کوچک برای نمایش ASCII
    small_grid = cv2.resize(photo_grid, (60, 30))
    gray_grid = cv2.cvtColor(small_grid, cv2.COLOR_BGR2GRAY)
    
    # کاراکترهای ASCII برای نمایش
    ascii_chars = "@%#*+=-:. "
    
    for y in range(30):
        line = "│ "
        for x in range(60):
            pixel = gray_grid[y, x]
            char_idx = min(pixel // 32, len(ascii_chars) - 1)
            line += ascii_chars[char_idx]
        line += " │"
        print(line)
    
    print("└" + "─"*64 + "┘")
    
    # راهنمای مشاهده عکس‌ها
    print("\n نحوه مشاهده عکس‌ها:")
    print("1. به پوشه Download بروید")
    print("2. پوشه PhotoGrid را باز کنید")
    print("3. فایل photo_grid_...jpg را ببینید")
    
else:
    print("❌ هیچ عکسی گرفته نشد!")

print("\n✅ برنامه با موفقیت به پایان رسید")
print("[Program finished]")
 

saalek110

Well-Known Member
شرح کد پست قبل توسط هوش مصنوعی deepseek:

شرح قسمت‌های مهم:**

### **۱. بخش تنظیمات:**
```python
NUM_PHOTOS = 4 # تعداد عکس‌ها
DELAY_SECONDS = 5 # فاصله ۵ ثانیه
PHOTO_WIDTH = 320 # عرض تصویر
PHOTO_HEIGHT = 240 # ارتفاع تصویر
```
- تنظیم پارامترهای قابل تغییر
- رزولوشن پایین برای عملکرد بهتر روی تبلت

### **۲. مدیریت پوشه:**
```python
save_folder = "/storage/emulated/0/Download/PhotoGrid/"
os.makedirs(save_folder, exist_ok=True)
```
- استفاده از پوشه Download که دسترسی آسان دارد
- `exist_ok=True` یعنی اگر پوشه وجود داشت، خطا نده

### **۳. راه‌اندازی دوربین:**
```python
cap = cv2.VideoCapture(0) # 0 = دوربین اصلی
cap.set(cv2.CAP_PROP_FRAME_WIDTH, PHOTO_WIDTH) # تنظیم عرض
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, PHOTO_HEIGHT) # تنظیم ارتفاع
```
- `VideoCapture(0)`: باز کردن دوربین اصلی
- `set()`: تنظیم رزولوشن دوربین

### **۴. حلقه گرفتن عکس‌ها:**
```python
for i in range(NUM_PHOTOS):
ret, frame = cap.read() # خواندن فریم
cv2.imwrite(filename, frame) # ذخیره عکس
```
- `cap.read()`: گرفتن یک فریم از دوربین
- `cv2.imwrite()`: ذخیره عکس در فایل
- شمارش معکوس با `time.sleep(1)`

### **۵. اضافه کردن متن روی عکس:**
```python
cv2.putText(annotated_frame, f'Photo {i+1}', (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
```
- اضافه کردن شماره عکس و زمان
- موقعیت (x,y) = (10,30)
- رنگ (B,G,R) = (0,255,0) = سبز
- ضخامت = 2

### **۶. ایجاد گرید:**
```python
row1 = np.hstack((photos[0], photos[1])) # کنار هم
photo_grid = np.vstack((row1, row2)) # زیر هم
```
- `np.hstack()`: قرار دادن افقی (horizontal)
- `np.vstack()`: قرار دادن عمودی (vertical)
- ایجاد گرید ۲×۲

### **۷. نمایش ASCII در ترمینال:**
```python
small_grid = cv2.resize(photo_grid, (60, 30)) # کوچک کردن
gray_grid = cv2.cvtColor(small_grid, cv2.COLOR_BGR2GRAY) # خاکستری
```
- کوچک کردن تصویر برای نمایش در ترمینال
- تبدیل به خاکستری
- نگاشت پیکسل‌ها به کاراکترهای ASCII

## **خطاهای احتمالی و راه‌حل:**

### **اگر دوربین کار نکرد:**
```python
if not cap.isOpened():
print("❌ دوربین کار نمی‌کند")
exit()
```

### **اگر ذخیره فایل خطا داد:**
```python
try:
cv2.imwrite(filename, frame)
except:
print("⚠️ ذخیره نشد")
```

### **اگر عکس کمتری گرفته شد:**
```python
while len(photos) < 4:
black_img = np.zeros((PHOTO_HEIGHT, PHOTO_WIDTH, 3), dtype=np.uint8)
photos.append(black_img) # اضافه کردن تصویر سیاه
```

## **خروجی‌های برنامه:**

### **فایل‌های ایجاد شده:**
```
/storage/emulated/0/Download/PhotoGrid/
├── photo_1_024147.jpg # عکس اول
├── photo_2_024152.jpg # عکس دوم
├── photo_3_024157.jpg # عکس سوم
├── photo_4_024202.jpg # عکس چهارم
└── photo_grid_20260128_024142.jpg # گرید ترکیبی
```

### **نمایش در ترمینال:**
- شمارش معکوس برای هر عکس
- وضعیت ذخیره هر عکس
- پیش‌نمایش ASCII از گرید
- گزارش کامل

## **چگونه تغییرش بدیم:**

### **برای ۱۰ عکس با فاصله ۲ ثانیه:**
```python
NUM_PHOTOS = 10
DELAY_SECONDS = 2
```

### **برای رزولوشن بالاتر:**
```python
PHOTO_WIDTH = 640
PHOTO_HEIGHT = 480
```

### **برای ذخیره در پوشه متفاوت:**
```python
save_folder = "/storage/emulated/0/DCIM/MyPhotos/"
``
 

saalek110

Well-Known Member
برنامه نشان دادن تصویر دوربین:

Python:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

print(" نمایش ساده دوربین")

cap = cv2.VideoCapture(0)
cap.set(3, 320)  # عرض
cap.set(4, 240)  # ارتفاع

# ایجاد پنجره
fig, ax = plt.subplots()
img_display = ax.imshow(np.zeros((240, 320, 3), dtype=np.uint8))
ax.axis('off')
ax.set_title('دوربین تبلت')

def update(frame):
    ret, frame = cap.read()
    if ret:
        # تبدیل BGR به RGB
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        img_display.set_data(frame_rgb)
    return [img_display]

print("✅ دوربین فعال - برای خروج پنجره را ببندید")

ani = FuncAnimation(fig, update, interval=50, blit=True)
plt.show()

cap.release()
print("✅ برنامه پایان یافت")
 

saalek110

Well-Known Member
دوربینی که حالات مختلف دارد مثلا نمایش لبه ها ، فقط قرمز ، معکوس و ...:
Python:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib.widgets as widgets

print(" دوربین با دکمه‌های روی صفحه")

# راه‌اندازی دوربین
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

# حالت‌های مختلف
modes = [
    ("عادی", "normal"),
    ("خاکستری", "gray"),
    ("لبه‌ها", "edges"),
    ("فقط قرمز", "red"),
    ("فقط آبی", "blue"),
    ("فقط سبز", "green"),
    ("معکوس", "invert"),
    ("محو", "blur")
]

current_mode = 0

# ایجاد پنجره اصلی
fig = plt.figure(figsize=(10, 7))
fig.suptitle('دوربین تبلت - کنترل با دکمه', fontsize=14)

# بخش نمایش تصویر
ax_camera = plt.axes([0.1, 0.3, 0.8, 0.6])
img_display = ax_camera.imshow(np.zeros((240, 320, 3), dtype=np.uint8))
ax_camera.axis('off')
mode_text = ax_camera.text(10, 30, 'حالت: عادی', color='white', fontsize=12,
                          bbox=dict(facecolor='black', alpha=0.7))

# ایجاد دکمه‌ها
buttons = []
button_axes = []

for i, (name, mode) in enumerate(modes):
    row = i // 4  # 4 دکمه در هر ردیف
    col = i % 4
    ax = plt.axes([0.1 + col*0.2, 0.15 - row*0.07, 0.18, 0.05])
    button = widgets.Button(ax, name)
    button_axes.append(ax)
    buttons.append(button)

# دکمه عکس
ax_photo = plt.axes([0.7, 0.05, 0.2, 0.05])
btn_photo = widgets.Button(ax_photo, ' عکس بگیر')

# تابع پردازش فریم
def process_frame(frame, mode_name):
    if mode_name == "normal":
        return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    elif mode_name == "gray":
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        return cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)
    elif mode_name == "edges":
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        edges = cv2.Canny(gray, 50, 150)
        return cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
    elif mode_name == "red":
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, np.array([0,100,100]), np.array([10,255,255]))
        result = cv2.bitwise_and(frame, frame, mask=mask)
        return cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
    elif mode_name == "blue":
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, np.array([100,100,100]), np.array([130,255,255]))
        result = cv2.bitwise_and(frame, frame, mask=mask)
        return cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
    elif mode_name == "green":
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, np.array([40,100,100]), np.array([80,255,255]))
        result = cv2.bitwise_and(frame, frame, mask=mask)
        return cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
    elif mode_name == "invert":
        inverted = cv2.bitwise_not(frame)
        return cv2.cvtColor(inverted, cv2.COLOR_BGR2RGB)
    elif mode_name == "blur":
        blurred = cv2.GaussianBlur(frame, (15, 15), 0)
        return cv2.cvtColor(blurred, cv2.COLOR_BGR2RGB)
    return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

# تابع آپدیت تصویر
def update(frame_num):
    ret, frame = cap.read()
    if ret:
        mode_name = modes[current_mode][1]
        processed = process_frame(frame, mode_name)
        img_display.set_data(processed)
        mode_text.set_text(f'حالت: {modes[current_mode][0]}')
    return [img_display, mode_text]

# تابع‌های کلیک دکمه‌ها
def create_button_handler(index):
    def handler(event):
        global current_mode
        current_mode = index
        print(f"✅ حالت تغییر کرد به: {modes[index][0]}")
    return handler

# متصل کردن دکمه‌ها
for i, button in enumerate(buttons):
    button.on_clicked(create_button_handler(i))

# تابع عکس گرفتن
def take_photo(event):
    ret, frame = cap.read()
    if ret:
        import time
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        filename = f"/storage/emulated/0/DCIM/photo_{timestamp}.jpg"
        try:
            cv2.imwrite(filename, frame)
            print(f" عکس ذخیره شد: {filename}")
        except:
            print("⚠️ خطا در ذخیره عکس")

btn_photo.on_clicked(take_photo)

print("\n راهنمای استفاده:")
print("- روی دکمه‌های پایین صفحه ضربه بزنید")
print("- دکمه  برای عکس گرفتن")
print("- برای خروج پنجره را ببندید")
print("-" * 40)

# شروع انیمیشن
ani = FuncAnimation(fig, update, interval=50, blit=True)
plt.show()

cap.release()
print("✅ برنامه پایان یافت")

یکسری دکمه زیر تصویر هست برای تغییر حالت دوربین.
عکس هم میگیره میره به پوشه Dcim
 

saalek110

Well-Known Member
تصویر دوربین را نشان می دهد و مربع ها و مستطیل ها را با نقطه هایی در گوشه هایشان مشخص می کند:

Python:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

print("=" * 50)
print(" تشخیص مربع/مستطیل با دوربین تبلت")
print("=" * 50)

# راه‌اندازی دوربین
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

print("✅ دوربین فعال شد")

# ایجاد پنجره
fig, ax = plt.subplots()
img_display = ax.imshow(np.zeros((240, 320, 3), dtype=np.uint8))
ax.axis('off')
ax.set_title('تشخیص مربع/مستطیل - در حال پردازش...')

def detect_shapes(frame):
    """تشخیص مربع‌ها و مستطیل‌ها در تصویر"""
    # کپی از تصویر اصلی برای رسم
    output = frame.copy()
    
    # تبدیل به خاکستری
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # کاهش نویز
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    
    # تشخیص لبه‌ها
    edges = cv2.Canny(blurred, 50, 150)
    
    # پیدا کردن کانتورها
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    shapes_detected = 0
    
    for contour in contours:
        # محاسبه مساحت
        area = cv2.contourArea(contour)
        
        # نادیده گرفتن اشیاء خیلی کوچک
        if area < 500:
            continue
        
        # محاسبه محیط
        perimeter = cv2.arcLength(contour, True)
        
        # تقریب کانتور به چندضلعی
        epsilon = 0.04 * perimeter  # 4% از محیط
        approx = cv2.approxPolyDP(contour, epsilon, True)
        
        # تعداد گوشه‌ها
        num_corners = len(approx)
        
        # اگر ۴ گوشه داشت (مربع یا مستطیل)
        if num_corners == 4:
            # رسم کانتور
            cv2.drawContours(output, [approx], -1, (0, 255, 0), 2)
            
            # رسم نقاط روی گوشه‌ها
            for point in approx:
                x, y = point[0]
                cv2.circle(output, (x, y), 5, (0, 0, 255), -1)  # نقاط قرمز
            
            # رسم خطوط بین گوشه‌ها
            for i in range(4):
                x1, y1 = approx[i][0]
                x2, y2 = approx[(i + 1) % 4][0]
                cv2.line(output, (x1, y1), (x2, y2), (255, 0, 0), 2)
            
            # محاسبه مرکز
            M = cv2.moments(contour)
            if M["m00"] != 0:
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
                cv2.circle(output, (cX, cY), 3, (255, 255, 0), -1)  # مرکز آبی
            
            shapes_detected += 1
    
    return output, shapes_detected

def update(frame_num):
    # خواندن فریم
    ret, frame = cap.read()
    
    if not ret:
        return [img_display]
    
    # تشخیص اشکال
    processed_frame, shapes_count = detect_shapes(frame)
    
    # تبدیل به RGB برای نمایش
    frame_rgb = cv2.cvtColor(processed_frame, cv2.COLOR_BGR2RGB)
    img_display.set_data(frame_rgb)
    
    # آپدیت عنوان
    if shapes_count > 0:
        ax.set_title(f'تشخیص مربع/مستطیل - {shapes_count} شکل یافت شد', color='green')
    else:
        ax.set_title('تشخیص مربع/مستطیل - در حال جستجو...', color='blue')
    
    return [img_display]

print("\n ویژگی‌ها:")
print("- مستطیل‌ها با خط آبی")
print("- گوشه‌ها با نقطه قرمز")
print("- مرکز با نقطه زرد")
print("- کانتور با خط سبز")
print("=" * 40)
print("\n در حال پردازش تصویر...")

# شروع انیمیشن
ani = FuncAnimation(fig, update, interval=50, blit=True, cache_frame_data=False)
plt.show()

# آزاد کردن دوربین
cap.release()
print("\n✅ برنامه پایان یافت")
 

saalek110

Well-Known Member
نسخه دیگری از برنامه پست قبل که متنی هم روی مستطیل پیدا شده می نویسد:

Python:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

print("⚙️ تشخیص شکل با تنظیمات")

cap = cv2.VideoCapture(0)
cap.set(3, 320)
cap.set(4, 240)

fig, ax = plt.subplots()
img_display = ax.imshow(np.zeros((240, 320, 3), dtype=np.uint8))
ax.axis('off')

# تنظیمات قابل تغییر
MIN_AREA = 500      # حداقل مساحت
MAX_AREA = 20000    # حداکثر مساحت
SQUARE_RATIO = 0.8  # حداقل نسبت برای مربع بودن

def update(frame_num):
    ret, frame = cap.read()
    
    if ret:
        output = frame.copy()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        blurred = cv2.GaussianBlur(gray, (7, 7), 1.5)
        edges = cv2.Canny(blurred, 50, 150)
        
        contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        
        for contour in contours:
            area = cv2.contourArea(contour)
            
            if MIN_AREA < area < MAX_AREA:
                perimeter = cv2.arcLength(contour, True)
                approx = cv2.approxPolyDP(contour, 0.04 * perimeter, True)
                
                if len(approx) == 4:
                    # رسم گوشه‌ها
                    for point in approx:
                        x, y = point[0]
                        cv2.circle(output, (x, y), 8, (0, 0, 255), -1)
                    
                    # تشخیص مربع یا مستطیل
                    x, y, w, h = cv2.boundingRect(approx)
                    ratio = w / float(h)
                    
                    if SQUARE_RATIO <= ratio <= 1/SQUARE_RATIO:
                        cv2.drawContours(output, [approx], -1, (0, 255, 0), 3)
                        cv2.putText(output, 'SQUARE', (x, y-10),
                                   cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
                    else:
                        cv2.drawContours(output, [approx], -1, (255, 0, 0), 3)
                        cv2.putText(output, 'RECT', (x, y-10),
                                   cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2)
        
        frame_rgb = cv2.cvtColor(output, cv2.COLOR_BGR2RGB)
        img_display.set_data(frame_rgb)
    
    return [img_display]

print(f"\n⚙️ تنظیمات فعلی:")
print(f"- حداقل مساحت: {MIN_AREA}")
print(f"- حداکثر مساحت: {MAX_AREA}")
print(f"- حساسیت مربع بودن: {SQUARE_RATIO}")
print("\n در حال اجرا...")

ani = FuncAnimation(fig, update, interval=50, blit=True)
plt.show()

cap.release()
print("\n✅ پایان")
 

saalek110

Well-Known Member
این برنامه را هوش مصنوعی Deepseek داد.چند برنامه پستهای قبلی هم همچنین.

برنامه تشخیص دست:

Python:
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
import time

def detect_fingers(frame, roi_x, roi_y, roi_width, roi_height):
    """تشخیص انگشتان در ناحیه مشخص"""
    # استخراج ROI
    roi = frame[roi_y:roi_y+roi_height, roi_x:roi_x+roi_width]
   
    # تبدیل به HSV برای تشخیص پوست
    hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
   
    # محدوده رنگ پوست در HSV
    lower_skin = np.array([0, 20, 70], dtype=np.uint8)
    upper_skin = np.array([20, 255, 255], dtype=np.uint8)
   
    # ماسک پوست
    skin_mask = cv2.inRange(hsv, lower_skin, upper_skin)
   
    # اعمال مورفولوژی برای بهبود ماسک
    kernel = np.ones((3, 3), np.uint8)
    skin_mask = cv2.morphologyEx(skin_mask, cv2.MORPH_OPEN, kernel, iterations=2)
    skin_mask = cv2.morphologyEx(skin_mask, cv2.MORPH_CLOSE, kernel, iterations=2)
    skin_mask = cv2.dilate(skin_mask, kernel, iterations=1)
   
    # پیدا کردن کانتورها
    contours, _ = cv2.findContours(skin_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
   
    if len(contours) == 0:
        return roi, skin_mask, 0, roi
   
    # پیدا کردن بزرگترین کانتور (احتمالاً دست)
    max_contour = max(contours, key=cv2.contourArea)
   
    # اگر کانتور خیلی کوچک است، نادیده بگیر
    if cv2.contourArea(max_contour) < 5000:
        return roi, skin_mask, 0, roi
   
    # پیدا کردن محدب‌ترین نقاط
    hull = cv2.convexHull(max_contour, returnPoints=False)
   
    # پیدا کردن نقاط فرورفته
    defects = cv2.convexityDefects(max_contour, hull)
   
    if defects is None:
        return roi, skin_mask, 1, roi
   
    # شمارش نقاط فرورفته (انگشتان)
    finger_count = 0
    roi_with_marks = roi.copy()
   
    # نقاط شروع و پایان انگشتان
    finger_points = []
   
    for i in range(defects.shape[0]):
        s, e, f, d = defects[i, 0]
        start = tuple(max_contour[s][0])
        end = tuple(max_contour[e][0])
        far = tuple(max_contour[f][0])
       
        # محاسبه طول اضلاع مثلث
        a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
        b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
        c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
       
        # محاسبه زاویه
        angle = math.acos((b**2 + c**2 - a**2) / (2*b*c)) * 180/math.pi
       
        # اگر زاویه کمتر از 90 درجه باشد، یک فضای بین انگشتی است
        if angle <= 80:  # آستانه حساس‌تر
            finger_count += 1
            finger_points.append(far)
            cv2.circle(roi_with_marks, far, 8, (0, 255, 0), -1)
            cv2.line(roi_with_marks, start, end, (0, 0, 255), 2)
   
    # تعداد انگشتان = تعداد فضاهای بین انگشتی + 1
    if finger_count > 0:
        finger_count += 1
   
    # حداکثر 5 انگشت
    finger_count = min(finger_count, 5)
   
    # اگر هیچ فضای بین انگشتی پیدا نشد، احتمالاً مشت است
    if finger_count == 0 and cv2.contourArea(max_contour) > 15000:
        finger_count = 1  # احتمالاً مشت
   
    # رسم کانتور دست
    cv2.drawContours(roi_with_marks, [max_contour], -1, (255, 0, 0), 2)
   
    return roi, skin_mask, finger_count, roi_with_marks

# روشن کردن دوربین
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("خطا در باز کردن دوربین!")
    exit()

print("=" * 50)
print("برنامه تشخیص انگشتان دست")
print("=" * 50)
print("دستورالعمل:")
print("1. دست خود را در ناحیه سبز رنگ قرار دهید")
print("2. کف دست رو به دوربین باشد")
print("3. انگشتان را باز کنید")
print("4. برای خروج پنجره را ببندید")
print("=" * 50)

# تنظیمات ROI
roi_width = 300
roi_height = 300

# ایجاد پنجره نمایش
plt.ion()
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 8))
fig.suptitle('تشخیص انگشتان دست - برای خروج پنجره را ببندید', fontsize=14, fontweight='bold')

try:
    frame_count = 0
    last_finger_count = 0
   
    while True:
        ret, frame = cap.read()
        if not ret:
            print("خطا در خواندن از دوربین!")
            break
       
        # برعکس کردن تصویر
        frame = cv2.flip(frame, 1)
       
        # تعیین موقعیت ROI
        height, width = frame.shape[:2]
        roi_x = width // 2 - roi_width // 2
        roi_y = height // 2 - roi_height // 2
       
        # تشخیص انگشتان
        roi_original, skin_mask, finger_count, roi_marked = detect_fingers(
            frame, roi_x, roi_y, roi_width, roi_height
        )
       
        # رسم ROI روی فریم اصلی
        cv2.rectangle(frame, (roi_x, roi_y),
                     (roi_x + roi_width, roi_y + roi_height),
                     (0, 255, 0), 2)
       
        # نمایش تعداد انگشتان روی فریم اصلی
        text = f"تعداد انگشتان: {finger_count}"
        cv2.putText(frame, text, (roi_x, roi_y - 10),
                   cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
       
        # نمایش پیام توصیه
        advice_text = ""
        advice_color = (0, 255, 0)
       
        if finger_count == 0:
            advice_text = "دستت رو بذار توی کادر سبز!"
            advice_color = (0, 0, 255)
        elif finger_count == 1:
            advice_text = "انگشتات رو باز کن!"
            advice_color = (0, 165, 255)  # نارنجی
        elif finger_count == 5:
            advice_text = "عالی! همه انگشتان دیده می‌شوند"
            advice_color = (0, 255, 0)
        else:
            advice_text = f"انگشتان شناسایی شده: {finger_count}"
            advice_color = (255, 255, 0)
       
        cv2.putText(frame, advice_text, (20, 50),
                   cv2.FONT_HERSHEY_SIMPLEX, 0.8, advice_color, 2)
       
        # فقط هر 10 فریم یکبار چاپ کن
        frame_count += 1
        if frame_count % 10 == 0 or finger_count != last_finger_count:
            print(f"انگشتان تشخیص داده شده: {finger_count} - {advice_text}")
            last_finger_count = finger_count
       
        # تبدیل به RGB برای نمایش
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        roi_rgb = cv2.cvtColor(roi_original, cv2.COLOR_BGR2RGB)
        mask_rgb = cv2.cvtColor(skin_mask, cv2.COLOR_GRAY2RGB)
        marked_rgb = cv2.cvtColor(roi_marked, cv2.COLOR_BGR2RGB)
       
        # پاک کردن و به‌روزرسانی نمودارها
        ax1.clear()
        ax2.clear()
        ax3.clear()
        ax4.clear()
       
        ax1.imshow(frame_rgb)
        ax1.set_title('تصویر اصلی با ROI')
        ax1.axis('off')
       
        ax2.imshow(roi_rgb)
        ax2.set_title('ناحیه دست (ROI)')
        ax2.axis('off')
       
        ax3.imshow(marked_rgb)
        ax3.set_title(f'تشخیص انگشتان ({finger_count} انگشت)')
        ax3.axis('off')
       
        ax4.imshow(mask_rgb)
        ax4.set_title('ماسک پوست')
        ax4.axis('off')
       
        plt.tight_layout()
        plt.draw()
        plt.pause(0.001)
       
        # توقف کوتاه
        time.sleep(0.03)
       
        # بررسی بسته شدن پنجره
        if not plt.fignum_exists(fig.number):
            print("پنجره بسته شد. خروج از برنامه...")
            break

except KeyboardInterrupt:
    print("\nبرنامه توسط کاربر متوقف شد.")
except Exception as e:
    print(f"خطا: {e}")
finally:
    # آزاد کردن منابع
    cap.release()
    plt.close('all')
    print("\n" + "=" * 50)
    print("برنامه با موفقیت پایان یافت.")
    print("=" * 50)
 

saalek110

Well-Known Member
برنامه شمارش انگشتان از deepseek:

به شکل عدد ۱ تا ۵ میگه

فکر کنم دنبال رنگ پوست می گرده برنامه ، خودتان کد را بخوانید....
شاید پشت دست اگر سفید باشه و رنگ پوست نباشه کمک بکنه....
من انگشتان را باز و بسته کردم. مثلا علامت پیروزی که دو انگشت است ولی گاهی انگشت شصت که بسته شده را هم می شمارد و می گوید ۳ تا. در کل کار می کنه ولی نمیشه فعلا بهش اعتماد کرد و به عنوان راه ارتباطی برای دستور دادن استفاده کرد. البته من اولین باره دارم از این برنامه استفاده می کنم و شاید با تغییر محیط پیرامون یا تغییر کدها بشه درستش کرد. فعلا گزارش اولیه دادم. ولی برنامه جالبی است.

Python:
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
import time
import os

print(" سیستم کنترل با انگشتان دست")
print("=" * 50)
print("دستورات:")
print("  0 انگشت (مشت)  =  خروج")
print("  1 انگشت        =  افزایش صدا")
print("  2 انگشت        =  کاهش صدا")
print("  3 انگشت        = ⏯️ پخش/مکث")
print("  4 انگشت        = ⏭️ بعدی")
print("  5 انگشت        = ⏮️ قبلی")
print("=" * 50)
print(" دستورالعمل:")
print("  1. دست خود را در مرکز تصویر قرار دهید")
print("  2. کف دست رو به دوربین باشد")
print("  3. انگشتان را باز کنید")
print("  4. برای خروج پنجره را ببندید")
print("=" * 50)

# تابع تشخیص انگشتان
def count_fingers_from_mask(mask):
    """شمارش انگشتان از ماسک باینری"""
    contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
   
    if len(contours) == 0:
        return 0, None, []
   
    # بزرگترین کانتور (دست)
    max_contour = max(contours, key=cv2.contourArea)
   
    # اگر خیلی کوچک است، نادیده بگیر
    if cv2.contourArea(max_contour) < 3000:
        return 0, None, []
   
    # پیدا کردن نقاط محدب
    hull = cv2.convexHull(max_contour, returnPoints=False)
    defects = cv2.convexityDefects(max_contour, hull)
   
    if defects is None:
        return 1, max_contour, []
   
    # شمارش فضاهای بین انگشتی
    finger_count = 0
    defect_points = []
   
    for i in range(defects.shape[0]):
        s, e, f, d = defects[i, 0]
        start = tuple(max_contour[s][0])
        end = tuple(max_contour[e][0])
        far = tuple(max_contour[f][0])
       
        # محاسبه زاویه
        a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
        b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
        c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
       
        angle = math.acos((b**2 + c**2 - a**2) / (2 * b * c)) * 180 / math.pi
       
        # اگر زاویه کمتر از 90 درجه باشد
        if angle < 90:
            finger_count += 1
            defect_points.append(far)
   
    # تعداد انگشتان = فضاهای بین انگشتی + 1
    if finger_count > 0:
        finger_count += 1
   
    # حداکثر 5 انگشت
    finger_count = min(finger_count, 5)
   
    # اگر هیچ انگشتی پیدا نشد اما کانتور بزرگ است
    if finger_count == 0 and cv2.contourArea(max_contour) > 10000:
        finger_count = 0  # مشت
   
    return finger_count, max_contour, defect_points

# تابع اجرای دستور
def execute_command(finger_count, last_command):
    """اجرای دستور بر اساس تعداد انگشتان"""
    commands = {
        0: " خروج از برنامه",
        1: " افزایش صدا",
        2: " کاهش صدا",
        3: "⏯️ پخش/مکث",
        4: "⏭️ آهنگ بعدی",
        5: "⏮️ آهنگ قبلی"
    }
   
    command = commands.get(finger_count, "در حال تشخیص...")
   
    # فقط اگر دستور تغییر کرده باشد
    if command != last_command:
        print(f"✋ انگشتان: {finger_count} → {command}")
       
        # در اینجا می‌توانید کدهای واقعی برای اجرای دستورات را اضافه کنید
        # مثلاً:
        # if finger_count == 1:
        #     os.system("amixer -D pulse sset Master 5%+")
        # elif finger_count == 2:
        #     os.system("amixer -D pulse sset Master 5%-")
   
    return command

# راه‌اندازی دوربین
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("❌ خطا در باز کردن دوربین!")
    exit()

# ایجاد پنجره Matplotlib
plt.ion()
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
fig.suptitle(' سیستم کنترل با انگشتان دست', fontsize=16, fontweight='bold')

# متغیرهای برنامه
last_command = ""
last_finger_count = -1
frame_count = 0

try:
    print(" در حال راه‌اندازی دوربین...")
   
    while True:
        ret, frame = cap.read()
        if not ret:
            print("❌ خطا در خواندن از دوربین!")
            break
       
        # برعکس کردن تصویر (آینه‌ای)
        frame = cv2.flip(frame, 1)
        h, w = frame.shape[:2]
       
        # تعریف ناحیه ROI (مرکز تصویر)
        roi_size = min(300, h - 100, w - 100)
        roi_x = w // 2 - roi_size // 2
        roi_y = h // 2 - roi_size // 2
       
        # استخراج ROI
        roi = frame[roi_y:roi_y+roi_size, roi_x:roi_x+roi_size]
       
        # 1. تبدیل به HSV برای تشخیص پوست
        hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
       
        # محدوده رنگ پوست (قابل تنظیم)
        lower_skin1 = np.array([0, 30, 60])
        upper_skin1 = np.array([20, 255, 255])
        lower_skin2 = np.array([170, 30, 60])
        upper_skin2 = np.array([180, 255, 255])
       
        # ایجاد ماسک پوست
        mask1 = cv2.inRange(hsv, lower_skin1, upper_skin1)
        mask2 = cv2.inRange(hsv, lower_skin2, upper_skin2)
        skin_mask = cv2.bitwise_or(mask1, mask2)
       
        # 2. بهبود ماسک
        kernel = np.ones((3, 3), np.uint8)
        skin_mask = cv2.morphologyEx(skin_mask, cv2.MORPH_OPEN, kernel, iterations=2)
        skin_mask = cv2.morphologyEx(skin_mask, cv2.MORPH_CLOSE, kernel, iterations=2)
        skin_mask = cv2.dilate(skin_mask, kernel, iterations=1)
       
        # 3. تشخیص انگشتان
        finger_count, hand_contour, defect_points = count_fingers_from_mask(skin_mask)
       
        # 4. اجرای دستور
        last_command = execute_command(finger_count, last_command)
       
        # 5. آماده‌سازی تصاویر برای نمایش
        # تصویر اصلی با ROI
        frame_display = frame.copy()
        cv2.rectangle(frame_display, (roi_x, roi_y),
                     (roi_x + roi_size, roi_y + roi_size),
                     (0, 255, 0), 3)
        cv2.putText(frame_display, f'انگشتان: {finger_count}',
                   (20, 50), cv2.FONT_HERSHEY_SIMPLEX,
                   1, (0, 255, 255), 2)
        cv2.putText(frame_display, last_command,
                   (20, 100), cv2.FONT_HERSHEY_SIMPLEX,
                   0.8, (255, 100, 100), 2)
       
        # ROI اصلی
        roi_display = roi.copy()
       
        # ماسک پوست
        mask_display = cv2.cvtColor(skin_mask, cv2.COLOR_GRAY2BGR)
       
        # ROI با علامت‌گذاری
        roi_marked = roi.copy()
        if hand_contour is not None:
            # رسم کانتور دست
            cv2.drawContours(roi_marked, [hand_contour], -1, (255, 0, 0), 2)
           
            # نقاط بین انگشتی
            for point in defect_points:
                cv2.circle(roi_marked, point, 8, (0, 255, 0), -1)
           
            # نمایش تعداد انگشتان
            cv2.putText(roi_marked, f'{finger_count}',
                       (30, 50), cv2.FONT_HERSHEY_SIMPLEX,
                       1.5, (0, 0, 255), 3)
       
        # هیستوگرام HSV
        roi_hsv_display = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
       
        # 6. تبدیل BGR به RGB برای Matplotlib
        frame_rgb = cv2.cvtColor(frame_display, cv2.COLOR_BGR2RGB)
        roi_rgb = cv2.cvtColor(roi_display, cv2.COLOR_BGR2RGB)
        mask_rgb = cv2.cvtColor(mask_display, cv2.COLOR_BGR2RGB)
        marked_rgb = cv2.cvtColor(roi_marked, cv2.COLOR_BGR2RGB)
       
        # 7. پاکسازی و نمایش
        axes[0, 0].clear()
        axes[0, 1].clear()
        axes[0, 2].clear()
        axes[1, 0].clear()
        axes[1, 1].clear()
       
        axes[0, 0].imshow(frame_rgb)
        axes[0, 0].set_title(' تصویر اصلی')
        axes[0, 0].axis('off')
       
        axes[0, 1].imshow(roi_rgb)
        axes[0, 1].set_title('✋ ناحیه دست')
        axes[0, 1].axis('off')
       
        axes[0, 2].imshow(mask_rgb)
        axes[0, 2].set_title(' ماسک پوست')
        axes[0, 2].axis('off')
       
        axes[1, 0].imshow(marked_rgb)
        axes[1, 0].set_title(f' تشخیص ({finger_count} انگشت)')
        axes[1, 0].axis('off')
       
        axes[1, 1].imshow(roi_hsv_display)
        axes[1, 1].set_title(' فضای رنگ HSV')
        axes[1, 1].axis('off')
       
        # خالی کردن یک محور برای نمایش وضعیت
        axes[1, 2].clear()
        axes[1, 2].text(0.5, 0.5, f'دستور فعلی:\n{last_command}',
                       ha='center', va='center', fontsize=14)
        axes[1, 2].set_title(' وضعیت سیستم')
        axes[1, 2].axis('off')
       
        plt.tight_layout()
        plt.draw()
        plt.pause(0.01)
       
        frame_count += 1
       
        # توقف کوتاه
        time.sleep(0.03)
       
        # بررسی بسته شدن پنجره
        if not plt.fignum_exists(fig.number):
            print("\n پنجره بسته شد. خروج از برنامه...")
            break

except KeyboardInterrupt:
    print("\n⏹️ برنامه توسط کاربر متوقف شد.")
except Exception as e:
    print(f"\n❌ خطا: {str(e)}")
finally:
    # آزاد کردن منابع
    cap.release()
    plt.close('all')
    print("\n" + "=" * 50)
    print("✅ برنامه با موفقیت پایان یافت.")
    print("=" * 50)
 
آخرین ویرایش:

saalek110

Well-Known Member
نظر پست قبل را ه deepseek گفتم. او گفت:

شما کاملاً درست می‌گویید! مشکل اصلی این است که:

1. برنامه دنبال رنگ پوست می‌گردد
2. تشخیص نقاط convexity defects خیلی دقیق نیست
3. گاهی انگشت شصت را اشتباه می‌شمارد

بیایید یک رویکرد جدید امتحان کنیم که:

1. از شکل دست استفاده کند نه رنگ پوست
2. نوک انگشتان را مستقیم تشخیص دهد
3. آستانه‌های بهتری داشته باشد

سالک: هوش مصنوعی دو برنامه دیگر داد ولی وضعیت بدتر از برنامه پست قبلی شد و فعلا من این برنامه را ادامه نمی دهم. ولی شما می توانید خودتان یا با کمک گرفتن از هوش مصنوعی ، برنامه های خلاقانه یعنی با روش های دیگر یا تکمیل تر بنویسید.

سالک: رنگ پس زمینه در بعضی برنامه ها مهم است. شاید در بعضی برنامه ها دستکش تیره کمک کند. منظورم از بعضی برنامه ها ، روش و کدی است که در برنامه استفاده شده.
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا