در این آموزش OpenCV با هم یاد میگیریم اشکال سادهای مثل مربع، دایره، خط، نوشته و … رو بر روی تصویر و با کمک OpenCV رسم کنیم.
برنامههای پردازش تصویر ساده رو در نظر بگیرد، در اکثر اونها ما یک «چیزی» رو در تصویر پیدا کریم، دور اون مربع کشیدم و بالاش یک توضیح داریم! به عنوان مثال صورت فرد رو پیدا کریم و نوشتیم “face”، در این آموزش یاد میگیرم که اون مریع، دایره و … رو چطور در OpenCV رسم کنیم:-)
OpenCV توابع آمادهای رو برای رسم شکلهای زیر در اختیار ما میگذاره:
- Line
- Circle
- Ellipse
- Rectangle
- polygon
- Text
بهتره با چندتا مثال یاد بگیریم چطور شکلهایی که در بالا گفتیم رو رسم کنیم.
اول از همه بیاید یک کادر خالی برای خودمون درست کنیم:
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کارهای سفید و مشکی رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم whiteFrame = 255 * np.ones((480,480,3), np.uint8) blackFrame = np.zeros((480,480,3), np.uint8) # کادرهایی که ایجاد کردیم رو نماش بدیم cv2.imshow("white frime", whiteFrame) cv2.imshow("black frame",blackFrame) # صبر میکنیم تا کاربر کلیدی را فشار دهد cv2.waitKey(0)
کاری که انجام دادیم این بود که به کمک کتابخانهی NumPy دو عدد ماتریس ۳×۴۸۰×۴۸۰ ایجاد کردیم، یکی با مقدار صفر و دیگری با مقدار ۱×۲۵۵ که طبق GBR اگر نمایشش بدیم اولی سیاه و اون یکی سفید خواهد شد، در ادامه با کادر سفیدی که ایجاد کردیم کار خواهیم کرد.
رسم پاره خط:
دستوری که برای رسم خط در OpenCV استفاده میکنیم به شکل زیر است:
cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
Parameters:
- img – Image.
- pt1 – First point of the line segment.
- pt2 – Second point of the line segment.
- color – Line color.
- thickness – Line thickness.
- lineType –Type of the line:
- LINE_8 (or omitted) – 8-connected line.
- LINE_4 – 4-connected line.
- LINE_AA – antialiased line.
- shift – Number of fractional bits in the point coordinates.
این تابع پارهخطی بین نقاط pt1 و pt2 برای ما رسم میکند.
برنامهی رسم یک پاره خط رو با هم ببینیم:
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کادر سفید رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم image = 255 * np.ones((480,480,3), np.uint8) # یک پاره خطر از نقطه (۵۰و۵۰)به (۴۰۰و۴۰۰) با رنگ قرمز و ضخامت ۵ رسم میکینم image = cv2.line(image,(50,50), (400,400), (0,0,255), 5) # تصویر رو نمایش میدهیم cv2.imshow("image", image) # صبر میکنیم تا کاربر یک کلید را فشار بدهد cv2.waitKey(0)
رسم دایره:
تابعی که برای رسم دایره استفاده میکنیم این ساختار رو داره:
cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]])
Parameters:
- img – Image where the circle is drawn.
- center – Center of the circle.
- radius – Radius of the circle.
- color – Circle color.
- thickness – Thickness of the circle outline, if positive. Negative thickness means that a filled circle is to be drawn.
- lineType – Type of the circle boundary..
- shift – Number of fractional bits in the coordinates of the center and in the radius value
برنامهی سادهی ترسم دایره در OpenCV:
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کادر سفید رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم image = 255 * np.ones((480,480,3), np.uint8) # دایرههامون رو روی کادر خالی رسم میکنیم image = cv2.circle(image,(100,150),25,(255,0,0),-1) image = cv2.circle(image,(100,150),45,(0,255,0),3) # کادرمون رو نمایش میدهیم cv2.imshow("image", image) # صبر میکنیم تا کاربر یک کلید را فشار بدهد cv2.waitKey(0)
در برنامهی بالا چیکار کردیم؟ دو دایره به مرکز (۱۰۰,۱۵۰) و به شعاعهای ۲۵ و ۴۵ رسم کردیم، به اعداد ضخامتی که وارد کردیم دقت کنید، دایرهی آبی رو -۱ دادیم که این مقدار منفی باعث میشه دایرهی تو پر داشته باشیم، ضخامت دایرهی سبز رو هم ۳ قرار دادهایم.
به شکل کلی اگر عدد ضخامت رو مقداری منفی قرار دهیم اون شکل توپر رسم خواهد شد.
رسم بیضی:
برای رسم بیضی ما بجز پارامترهایی که در رسم خط و دایره داشتیم زاویهی بییضی نسبت به خط افقی و همچین زاویهی شروع و پایان رسم بیضی رو هم مشخص میکنیم، تابع رسم بیضی به این صورته:
cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]])
Parameters:
- img – Image.
- center – Center of the ellipse.
- axes – Half of the size of the ellipse main axes.
- angle – Ellipse rotation angle in degrees.
- startAngle – Starting angle of the elliptic arc in degrees.
- endAngle – Ending angle of the elliptic arc in degrees.
- color – Ellipse color.
- thickness – Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn.
- lineType – Type of the ellipse boundary. .
- shift – Number of fractional bits in the coordinates of the center and values of axes.
که مقدار پارامترهای بالا مطابق شکل زیر اند:
اگر دقت کنید تعیین زاویهی شروع و پایان رسم بیضی به ما کمک میکنه بتونیم بیضی کامل و یا بخشی از بیضی رو داشته باشیم.
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کادر سفید رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم image = 255 * np.ones((480,480,3), np.uint8) # چندتا بیضی با پارامترهای مختلف رسم میکنیم image = cv2.ellipse(image, (240,240), (50,100) ,30, 0, 360, (255,0,0), 3) image = cv2.ellipse(image, (240,240), (50,100) ,-30, 45, 225, (0,255,0), 5) image = cv2.ellipse(image, (100,100), (90,45) ,90, 0, 180, (0,255,0), -1) # تصویر رو نمایش میدهیم cv2.imshow("image", image) # صبر میکنیم تا کاربر یک کلید را فشار بدهد cv2.waitKey(0)
رسم مربع و مستطیل:
دستور رسم مربع رو با هم ببینیم:
cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
Parameters:
- img – Image.
- pt1 – Vertex of the rectangle.
- pt2 – Vertex of the rectangle opposite to pt1 .
- rec – Alternative specification of the drawn rectangle.
- color – Rectangle color or brightness (grayscale image).
- thickness – Thickness of lines that make up the rectangle. Negative values, like CV_FILLED , mean that the function has to draw a filled rectangle.
- lineType – Type of the line.
- shift – Number of fractional bits in the point coordinates.
بسته به مقادیر pt1 و pt2 با دستور بالا ما میتوانیم مربع و یا مستطیل رو داشته باشیم:
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کادر سفید رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم image = 255 * np.ones((480,480,3), np.uint8) # با این دستور یک مربع رسم میکنیم image = cv2.rectangle(image, (100,100), (200,200), (255,255,0),-1) # با این دستور یک مستطیل رسم میکنیم image = cv2.rectangle(image, (220,200), (350,400), (0,255,250), 5) # تصویر رو نمایش میدهیم cv2.imshow("image", image) # صبر میکنیم تا کاربر یک کلید را فشار بدهد cv2.waitKey(0)
رسم چندضلعی:
به وسیلهی دستور زیر میتوانیم مجموعهای از نقاط رو به هم وصل کنیم تا یک چندضلعی داشته باشیم:
cv2.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]])
Parameters:
- img – Image.
- pts – Array of polygonal curves.
- npts – Array of polygon vertex counters.
- ncontours – Number of curves.
- isClosed – Flag indicating whether the drawn polylines are closed or not. If they are closed, the function draws a line from the last vertex of each curve to its first vertex.
- color – Polyline color.
- thickness – Thickness of the polyline edges.
- lineType – Type of the line segments.
- shift – Number of fractional bits in the vertex coordinates.
برای مثال ما پنج ضلعی و شکل یک فلش رو به کمک برنامهی زیر رسم میکنیم:
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کادر سفید رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم image = 255 * np.ones((480,480,3), np.uint8) # رسم ۵ ضلعی # نقاطی که میخواهیم به هم وصل بشن رو به ترتیب مشخص میکنیم pentagon = np.array([[60,120],[100,90],[140,120],[120,160],[80,160]], np.int32) # آرایهای ابعاد ارایه رو به (1,2) تغییر میدهیم pentagon = pentagon.reshape((-1,1,2)) # اون رو رسم میکنیم! img = cv2.polylines(image, [pentagon], True, (0,255,255),3) # رسم فلش # نقاطی که میخواهیم به هم وصل بشن رو به ترتیب مشخص میکنیم arrow = np.array([[200,220],[300,220],[300,200],[350,230],[300,260],[300,240],[200,240]], np.int32) # آرایهای ابعاد ارایه رو به (1,2) تغییر میدهیم arrow = arrow.reshape((-1,1,2)) # اون رو رسم میکنیم! arrow = cv2.polylines(image, [arrow], True, (255,0,255),3) # تصویر رو نمایش میدهیم cv2.imshow("image", image) # صبر میکنیم تا کاربر یک کلید را فشار بدهد cv2.waitKey(0)
گذاشتن متن روی عکس:
دستور زیر برای گذاشتن نوشته بر روی تصویر استفاده میشود:
cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])
Parameters:
- Img – Image.
- text – Text string to be drawn.
- org – Bottom-left corner of the text string in the image.
- font – CvFont structure initialized using InitFont().
- fontFace – Font type. each of the font ID’s can be combined with FONT_ITALIC to get the slanted letters.
- fontScale – Font scale factor that is multiplied by the font-specific base size.
- color – Text color.
- thickness – Thickness of the lines used to draw a text.
- lineType – Line type.
- bottomLeftOrigin – When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner.
لیست فونتهایی که میتونیم استفاده کنیم:
Font type:
- FONT_HERSHEY_SIMPLEX = 0,
- FONT_HERSHEY_PLAIN = 1,
- FONT_HERSHEY_DUPLEX = 2,
- FONT_HERSHEY_COMPLEX = 3,
- FONT_HERSHEY_TRIPLEX = 4,
- FONT_HERSHEY_COMPLEX_SMALL = 5,
- FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
- FONT_HERSHEY_SCRIPT_COMPLEX = 7
کد برنامه درج متن بر روی تصویر:
# کتابخانههای OpenCV و NumPy رو به فرا میخونیم. import cv2 import numpy as np # کادر سفید رو در اندازهی ۴۸۰*۴۸۰ تولید میکنیم image = 255 * np.ones((480,480,3), np.uint8) # یک متن روی تصویر درج میکنیم cv2.putText(image, "mh-salari.me", (130, 240), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2) # تصویر رو نمایش میدهیم cv2.imshow("image", image) # صبر میکنیم تا کاربر یک کلید را فشار بدهد cv2.waitKey(0)
برای کارهای پردازش تصویری که ما میخواهیم انجام بدیم توابع بالا کافیاند اما توابع دیگهای هم برای ترسیم داریم که در این لینک میتونید لیست کامل اونها رو ببنید.
جهت دانلودفایلهای این آموزش می تونید به گیتهاب من (به این آدرس) مراجعه کنید.
اگر میخواهید OpenCV رو بر روی اوبونتو نصب کنید به «آموزش نصب OpenCV 3 با Python 3 بر روی بر روی سیتمعامل ubuntu 17.10» مراجعه کنید.
قسمت قبلی این سری از نوشتهها هم این آموزش میشه:«اعمال مقدماتی بر روی عکس در OpenCV »
نویسنده: محمد حسین سالاری.