پیدا کردن الگو در تصویر توسط تابع matchTemplate
سلام و عصر بخیر.
امیدوارم جمعه خوبی داشته باشید. در پست امروز تصمیم دارم نحوه پیدا کردن یک الگو (Pattern) را درون یک تصویر با استفاده از OpenCV و تابع matchTemplate و زبان برنامه نویسی Python را یاد بدهم. برای انجام این کار به دو تصویر نیاز داریم. اول تصویر اصلی که می خواهیم درون آن به جستجو بپردازیم و دوم، تصویری که می خواهیم دنبال آن بگردیم. فرض کنید بخواهیم خرچنگ قرمز رنگی را درون تصویر بالا پیدا کنیم. خب اگر حوصله و وقت کافی دارید بهتره خودتون شروع به گشتن بکنید و شاید یعد از چند ساعت بتونید خرچنگ را پیدا کنید. اما اینجا قصد داریم تا با استفاده از پردازش تصویر، خیلی خیلی راحت تر و سریع تر خرچنگ رو پیدا کنیم. شکل زیر خرچنگ مورد نظر را انشان می دهد. پس بهتره وقت را تلف نکنیم و شروع به نوشتن کد کنیم.
1 2 3 |
# import the necessary packages import numpy as np import cv2 |
در ابتدا پکیج های مورد نظر را وارد کنید. دقیقاً مانند کدهای پیشین، numpy برای Numerical processing و cv2 برای OpenCV.
1 2 3 4 |
# load the puzzle and query images puzzle = cv2.imread("puzzle.jpg") query = cv2.imread("query.PNG") (queryHeight, queryWidth) = query.shape[:2] |
بعد از این که پکیج ها را فراخوانی کردیم نوبت به بارگذاری تصاویر می رسد. puzzle تصویری است که می خواهیم درون آن را جستجو کنیم و query، تصویر خرچنگی است که قرار است دنبال آن می گردیم.
در خط بعدی ابعاد تصویر خرچنگ را وارد دو متغیر می کنیم.
1 2 3 |
# find the query in the puzzle result = cv2.matchTemplate(puzzle, query, cv2.TM_CCOEFF) (_, _, minLoc, maxLoc) = cv2.minMaxLoc(result) |
در این قسمت با فراخوانی تابع matchTemplate، عملیات جستجو را آغاز می کنیم. ایت تابع دارای سه پارمتر ورودی است. اولین پارامتر مربوط به تصویر اصلی، دومین پارامتر تصویر خرچنگ و سومین پارامتر متد جستجو است.
بد نیست که توضیح مختصری در مورد نحوه کار این تابع بدهم. دستور matchTemplate یک پنجره به اندازه ابعاد تصویر query ایجاد می کند و آن را در سراسر تصویر اصلی از بالا-چپ تا پایین-راست حرکت می دهد و هرجایی که بهترین تطبیق را داشته باشد به خروجی می فرستد.
در مرحله بعدی مختصات نتیجه بدست آمده را با از دستور minMaxLoc بدست می آوریم.
1 2 3 4 |
# the puzzle image topLeft = maxLoc botRight = (topLeft[0] + queryWidth, topLeft[1] + queryHeight) roi = puzzle[topLeft[1]:botRight[1], topLeft[0]:botRight[0]] |
چون از متد TM_CCOEFF استفاده کرده بودیم، بنابراین مختصات نقطه بالا-چپ، بیشترین مقداری است که تابع minMaxLoc پیدا کرده است. برای پیدا کردن مختصات نقطه پایین-راست، طول و عرض نقطه بالا-چپ را با مختصات تصویر query جمع می کنیم.
محدوده ای که خرچنگ درون آن پیدا شده است را محاسبه و در متغیر roi تغییره می کنیم.
پیدا کردن الگو تمام شد. به همین سادگی. حالا بد نیست کمی به جنبه های زیبایی کد بپردازیم و الگوی پیدا شده را بر روی تصویر اصلی نشان بدهیم. برای این کار تمامی تصویر اصلی را تیره می کنیم و فقط محدوده ای که خرچنگ درون آن یافت شده است را روشن تر می کنیم.
1 2 3 4 |
# construct a darkened transparent 'layer' to darken everything # in the puzzle except for query mask = np.zeros(puzzle.shape, dtype = "uint8") puzzle = cv2.addWeighted(puzzle, 0.25, mask, 0.75, 0) |
توسط آرایه های np، یک ماسک با ابعاد تصویر اصلی و از نوع uint8 می سازیم.
سپس آن را با تصویر اصلی و به یک نسبت مشخص جمع می کنیم. برای این کار دستور addWeight مناسب خواهد بود.
1 2 3 4 5 6 7 8 9 |
# put the original query back in the image so that he is # 'brighter' than the rest of the image puzzle[topLeft[1]:botRight[1], topLeft[0]:botRight[0]] = roi # display the images res=cv2.resize(puzzle,(650,500),cv2.INTER_AREA) cv2.imshow("Puzzle",res ) cv2.imwrite("Matching.jpg",res) cv2.waitKey(0) |
در پایان و از لینک زیر می توانید کد را به همراه تصاویر نمونه دانلود نمایید. از نرم افزارهای OpenCV 3.0.0 و Python 2.7 برای کدنویسی استفاده شده است.
موفق باشید.
سلام میشه پیدا کردن یک تصویر در ویدیو هم اموزش بدید؟
متاسفانه وقت نمیکنم آموزشش رو بگذارم