خوراک پی سی کدنویس

ورود کاربران

آمار سایت

اعضا : 431
محتوا : 74
پیوندها : 6
بازدیدهای محتوا : 245418

حاضرین در سایت

 71 مهمان حاضر

برای نمایش بهتر سایت، از مرورگر استاندارد فایرفاکس استفاده کنید! مرورگر اینترنت اکسپلورر متعلق به دهه گذشته است!

firefox icon

Valid XHTML 1.0 Transitional Valid CSS!

پردازش تصویر به کمک OpenCV : لبه یابی و تغییر اندازه

2 امتیاز

در مثال قبل، نحوه استفاده از OpenCV را آموختیم. اکنون قصد داریم برنامه ای برای یافتن لبه های تصویر و تغییر اندازه آن بنویسیم. OpenCV توابع زیادی برای کار با تصاویر دارد. در این مثال از 5 تابع cvCanny، cvSobel، cvResize، cvConvertScale و cvSplit استفاده خواهیم کرد که هر کدام را اگر یک تازه کار بخواهد بنویسد شاید چند روز یا حتی چند هفته وقت بگیرد.

خوب بهتر است به کد برنامه نگاهی بیندازیم:

نکته: به دلیل خطاهای غیر قابل پیش بینی که در کلاسهای c++ معرفی شده در نسخه 2.1 اتفاق می افتد، فعلا از خیر این کلاسها می گذریم و از همان توابع C آن استفاده می کنیم.

 
// in the name of allah
// The second OpenCV example
// Working with some image processing functions like edge detectors
// Developed by http://www.P30CodeNevis.ir
// 2010-11-25
 
#include "cv.h"
#include "highgui.h"
 
//Canny Edge Detector
IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, int aperture)
{  
   if(in->nChannels != 1)
      return(0); //Canny only handles gray scale images
   IplImage* out = cvCreateImage( cvGetSize(in), IPL_DEPTH_8U, 1 );
   cvCanny( in, out, lowThresh, highThresh, aperture );
   return( out );
};
 
//Sobel Edge Detector
IplImage* doSobel( IplImage* in, int xOrder, int yOrder, int aperture)
{  
   if(in->nChannels != 1)
      return(0); //Sobel only handles gray scale images
   IplImage* temp = cvCreateImage( cvGetSize(in), IPL_DEPTH_16S, 1 );
   IplImage* out = cvCreateImage( cvGetSize(in), IPL_DEPTH_8U, 1 );
   cvSobel( in, temp, xOrder, yOrder, aperture );
   cvConvertScale(temp, out); 
   cvReleaseImage(&temp);
   return( out );
};
 
//Image Resize
IplImage* doResize( IplImage* in, int filter = CV_INTER_LINEAR ) 
{
   IplImage* out = cvCreateImage(
   cvSize( in->width/2, in->height/2 ), in->depth, in->nChannels );
   cvResize( in, out, filter );
   return( out );
};
 
int main( int argc, char** argv ) {
 
   const char* imagename = argc > 1 ? argv[1] : "camera-man.jpg";
   IplImage* img = cvLoadImage(imagename);
 
   IplImage* resized = doResize(img);
   IplImage* g = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
   cvSplit(img, 0, g, 0, 0);
   IplImage* cedge = doCanny(g, 50, 175, 3);
   IplImage* sedge = doSobel(g, 0, 1, 3);
 
   cvShowImage("Original", img);
   cvShowImage("Green Channel", g);
   cvShowImage("Resized", resized);
   cvShowImage("Canny Edge", cedge);
   cvShowImage("Sobel Edge", sedge);
 
   cvSaveImage("Green channel.jpg", g);
   cvSaveImage("Resized.jpg", resized);
   cvSaveImage("Canny Edge.jpg", cedge);
   cvSaveImage("Sobel Edge.jpg", sedge);
   cvWaitKey(0);
 
   // Release memory and destroy window
   cvReleaseImage( &resized );
   cvReleaseImage( &g );
   cvReleaseImage( &cedge );
   cvReleaseImage( &sedge );
   cvReleaseImage( &img );
   cvDestroyWindow( "Original" );
   cvDestroyWindow( "Green Channel" );
   cvDestroyWindow( "Resized" );
   cvDestroyWindow( "Canny Edge" );
   cvDestroyWindow( "Eobel Edge" );
 
   return(0);
}
 
 

بارگذاری تصویر مانند مثال قبل، یا از طریق خط فرمان است و یا تصویر camera-man.jpg که باید در مسیر برنامه باشد. برای تغییر اندازه تصویر اصلی از تابع cvResize استفاده می کنیم. این تابع که هم اسم آن و هم رفتار آن مطابق توایع مرسوم تغییر اندازه است، سه پارامتر می گیرد: اولی تصویر ورودی، دومی تصویر خروجی که میزان تغییر مقیاس هم از روی همین تصویر تعیین می شود و سومی نوع الگوریتم است که یکی از چهار مقدار CV_INTER_LINEAR, CV_INTER_NN, CV_INTER_AREA, CV_INTER_CUBIC را می گیرد. این مقادیر به ترتیب برای الگوریتمهای bilinear و binearest neighboura و pixel area resampling و bicubic می باشد. مناسب ترین روش از نظر سرعت و کیفیت همان bilinear است.

توابع cvCanny و cvSobel دو لبه یاب معروف هستند که اولی بار محاسباتی بسیار زیادی نسبت به سوبل دارد. در هر دو مورد، تصویر ورودی باید خاکستری باشد، لذا به کمک cvSplit ما تنها کانال green تصویر را گرفته و به عنوان ورودی به این توابع ارسال می کنیم. کانال green نماینده خوبی از سطح خاکستری تصویر است.

لبه یاب سوبل سه پارامتر می گیرد، اولی نحوه مشتق گیری در راستای افقی (0: عدم مشتق گیری، 1: مشتق اول و 2: مشتق دوم) دومی نحوه مشتق گیری در راستای عمودی و سومی اندازه فیلتر که غالبا 3*3 استفاده می شود. بهتر است تصویر خروجی لبه یاب سوبل از نوع IPL_DEPTH_16S باشد چرا که محاسبات داخلی منجر به مقادیری بیش از یک بایت می شود و لذا برای هر پیکسل از یک عدد صحیح 16 بیتی علامت دار استفاده می کنیم. لیکن برای نمایش تصویر ناچاریم دوباره آن را به IPL_DEPTH_8U (هر پیکسل معادل یک عدد 8 بیتی بدون علامت) برگردانیم که برای این کار از تابع cvConvertScale استفاده می کنیم.

لبه یاب کنی هم سه پارامتر می گیرد، دو تا آستانه پایین و بالا (هر کدام بین 0 و 255) و یکی اندازه فیلتری (مانند فیلتر سوبل) که در داخل canny استفاده می شود. جزئیات بیشتر را از اینجا بخوانید.

سایر کدهای برنامه برای نمایش و ذخیره سازی تصاویر و پاکسازی حافظه است که گمان نمی کنم نیاز به توضیح داشته باشد.

تصاویر خروجی برنامه:

camera man

تصویر ورودی: camera-man.jpg

 

Green channel

تصویر خاکستری (کانال سبز): Green channel.jpg

 

canny edge

تصویر لبه کنی: Canny Edge.jpg

 

Sobel Edge

تصویر لبه سوبل: Sobel Edge.jpg

 

down sampled image

تصویر کوچک شده: Resized.jpg

  • احمد  - تشکر
    avatar
    استاد یه مقدار بین دو آموزش فاصله افتاد گفتم نظرتون عوض شده.
    تشکر می کنم با اینکه وقت کمی دارید باز هم ادامه می دبد :cheer:
  • مسلم
    avatar
    سلام استاد
    با این که از پردازش تصویر یکم اطلاعات قبلی داشتم ولی از مطالب این بخش هیچی عایدم نشد
    اگه ممکنه یکم از بار تخصصیش کم کنین یا اینکه منبعی معرفی کنین که پیش زمینه های لازم رو داشته باشیم
    با تشکر
  • yalda65  - hi
    avatar
    سلام من میخام همین کد را در c# بنویسم از emgu باسد استفاده کنم؟دریت نمیاد یه برنامه نوشتم ولی تابع ها رو نمیشناسه! فرم را برام نمیاره. اگه ممکنه کمکم کنید
  • مدیر سایت
    avatar
    بله در #C باید از EMGU استفاده کنید ولی من با آن کار نکرده ام.
  • elahe  - تشکر
    avatar
    خیلی ممنون به خاطر آموزشتون :) خوشحال می شم ادامه بدید!
اظهار نظر
مشخصات شما:
گراواتار enabled
نظر:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):s:!::?::idea::arrow:
امنیت
کد آنتی اسپم نمایش داده شده در عکس را وارد کنید.