|
|
|
import cv2 |
|
import numpy as np |
|
from PIL import Image |
|
import pytesseract |
|
import logging |
|
from datetime import datetime |
|
|
|
class EngineeringDrawingAnalyzer: |
|
"""محلل الرسومات الهندسية المتقدم""" |
|
|
|
def __init__(self, claude_client=None): |
|
self.claude_client = claude_client |
|
self.supported_formats = ['.dwg', '.dxf', '.pdf', '.jpg', '.jpeg', '.png'] |
|
|
|
def analyze_drawing(self, file_path): |
|
"""تحليل الرسم الهندسي""" |
|
try: |
|
|
|
image = cv2.imread(file_path) |
|
|
|
|
|
lines, shapes = self._analyze_shapes(image) |
|
|
|
|
|
text, dimensions = self._extract_text_and_dimensions(image) |
|
|
|
|
|
if self.claude_client: |
|
drawing_info = { |
|
'lines': lines, |
|
'shapes': shapes, |
|
'text': text, |
|
'dimensions': dimensions |
|
} |
|
|
|
analysis_prompt = f""" |
|
قم بتحليل معلومات الرسم الهندسي التالية وتقديم: |
|
1. تحليل شامل للرسم |
|
2. تحديد التخصص (إنشائي، معماري، ميكانيكي، كهربائي) |
|
3. تحليل التفاصيل الفنية |
|
4. توصيات للتحسين |
|
5. تقدير التكاليف |
|
|
|
معلومات الرسم: |
|
{json.dumps(drawing_info, indent=2, ensure_ascii=False)} |
|
""" |
|
|
|
response = self.claude_client.messages.create( |
|
model="claude-3-sonnet-20240229", |
|
max_tokens=4000, |
|
temperature=0.7, |
|
messages=[{"role": "user", "content": analysis_prompt}] |
|
) |
|
|
|
ai_analysis = response.content[0].text |
|
else: |
|
ai_analysis = "تحليل الذكاء الاصطناعي غير متاح" |
|
|
|
return { |
|
'file_info': { |
|
'path': file_path, |
|
'type': os.path.splitext(file_path)[1], |
|
'size': os.path.getsize(file_path) |
|
}, |
|
'analysis': { |
|
'lines': lines, |
|
'shapes': shapes, |
|
'text': text, |
|
'dimensions': dimensions, |
|
'ai_analysis': ai_analysis |
|
} |
|
} |
|
|
|
except Exception as e: |
|
logging.error(f"خطأ في تحليل الرسم: {str(e)}") |
|
raise |
|
|
|
def _analyze_shapes(self, image): |
|
"""تحليل الخطوط والأشكال""" |
|
|
|
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) |
|
|
|
|
|
edges = cv2.Canny(gray, 50, 150) |
|
|
|
|
|
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100) |
|
|
|
|
|
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
|
|
|
shapes = [] |
|
for contour in contours: |
|
approx = cv2.approxPolyDP(contour, 0.04 * cv2.arcLength(contour, True), True) |
|
if len(approx) == 3: |
|
shapes.append('triangle') |
|
elif len(approx) == 4: |
|
shapes.append('rectangle') |
|
elif len(approx) == 5: |
|
shapes.append('pentagon') |
|
elif len(approx) > 5: |
|
shapes.append('circle') |
|
|
|
return { |
|
'line_count': len(lines) if lines is not None else 0, |
|
'line_angles': self._analyze_line_angles(lines) if lines is not None else [], |
|
'line_lengths': self._analyze_line_lengths(lines) if lines is not None else [] |
|
}, { |
|
'shape_count': len(shapes), |
|
'shape_types': dict(Counter(shapes)) |
|
} |
|
|
|
def _extract_text_and_dimensions(self, image): |
|
"""استخراج النص والأبعاد""" |
|
|
|
text = pytesseract.image_to_string(image, lang='ara+eng') |
|
|
|
|
|
dimensions = self._analyze_dimensions_from_text(text) |
|
|
|
return text, dimensions |
|
|
|
def _analyze_dimensions_from_text(self, text): |
|
"""تحليل الأبعاد من النص""" |
|
import re |
|
|
|
|
|
dimension_pattern = r'(\d+(?:\.\d+)?)\s*(م|متر|سم|مم|m|cm|mm)' |
|
|
|
|
|
dimensions = re.findall(dimension_pattern, text) |
|
|
|
|
|
processed_dimensions = [] |
|
for value, unit in dimensions: |
|
processed_dimensions.append({ |
|
'value': float(value), |
|
'unit': unit |
|
}) |
|
|
|
return processed_dimensions |
|
|