نوشتن الگوریتم پردازش تصویر Sobel - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

وبـــلاگ هــفت خــط کــد


آموزش های برنامه نویسی
۴۷ نفر آنلاین
۱ عضو و ۴۶ مهمان در سایت حاضرند

نوشتن الگوریتم پردازش تصویر Sobel

+3 امتیاز
465 بازدید
سلام. من کارشناسی ارشد نرم افزار هستم این ترم پردازش تصویر برداشتم.قرار شده خودمون تو C++ سوبل را پیاده سازی کنیم .دوستان میشه لطف کنید راهنماییم کنید که از کجا باید شروع کنم .یک سوال دیگه هم داشتم آیا تصویر باید حتماً grayscale باشه تا بشه سوبل را روی تصویر اجرا کرد؟

 

تشکر
سوال شده اسفند 1, 1392  بوسیله ی ابید (امتیاز 256)   1 3 27

1 پاسخ

+4 امتیاز
 
بهترین پاسخ
برای اینکه متوجه بشید که الگوریتم سوبل چطور عملیات مشتق را انجام میده با یک مثال یک بعدی بهتون توضیح میدم. یه شکل زیر دقیق کنید یک طیف رنگی خاکستری هستش
که مقادیر را بردیم روی نمودار.
 
حال ما قصد داریم موقعیتی را که در آن نمودار میزان تغییرات زیادی داشته را نمایش بدیم چون در واقع مشتق برای محاسبه میزان تغییرات مورد استفاده  قرار می گیره. البته بدست آوردن این تغییرات بستگی داره به اینکه شما تا چه فاصله به همسایگی هر نقطه نگاه کنید که اندازه این فاصله در پردازش تصویر تحت عنوان اندازه کرنل هستش.با بدست آوردن مشتق از نمودار بالا  نمودار زیر بدست میاد که شما در وسط تصویر یک ضربه یا peak می بینید.مقدار این نقطه از نمودار از مقادیر همسایگش بیشتره.
 
 
پس میشه نتیجه گرفت زمانی در تصویر لبه وجود داره که تغییرات در سطوح داشته باشیم یا تیره به روشن و یا برعکس. 
گاهی اوقات در کاربردهایی نیاز هستش که شما فقط لبه های افقی را داشته باشید که باید میزان تغییرات در راستای عمود را محاسبه کنید و گاهی هم به خطوط عمودی نیاز دارید که باید میزان تغییرات در راستای افق را بررسی نماید.
برای محاسبه مشتق در مقادیر یک بعدی کرنل -2 0 2 را با مقادیر کانولو می کنیم.
 
برای محاسبه مشتق در راستای افقی (Gx) و عمودی (Gy) هم از کرنل های زیر استفاده کنید.
 
#include<iostream>
#include<cmath>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;


// Computes the x component of the gradient vector
// at a given point in a image.
// returns gradient in the x direction
int xGradient(Mat image, int x, int y)
{
    return image.at<uchar>(y-1, x-1) +
                2*image.at<uchar>(y, x-1) +
                 image.at<uchar>(y+1, x-1) -
                  image.at<uchar>(y-1, x+1) -
                   2*image.at<uchar>(y, x+1) -
                    image.at<uchar>(y+1, x+1);
}

// Computes the y component of the gradient vector
// at a given point in a image
// returns gradient in the y direction

int yGradient(Mat image, int x, int y)
{
    return image.at<uchar>(y-1, x-1) +
                2*image.at<uchar>(y-1, x) +
                 image.at<uchar>(y-1, x+1) -
                  image.at<uchar>(y+1, x-1) -
                   2*image.at<uchar>(y+1, x) -
                    image.at<uchar>(y+1, x+1);
}

int main()
{

      Mat src, dst;
      int gx, gy, sum;

      // Load an image
      src = imread("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
      dst = src.clone();
      if( !src.data )
      { return -1; }


        for(int y = 0; y < src.rows; y++)
            for(int x = 0; x < src.cols; x++)
                dst.at<uchar>(y,x) = 0.0;

        for(int y = 1; y < src.rows - 1; y++){
            for(int x = 1; x < src.cols - 1; x++){
                gx = xGradient(src, x, y);
                gy = yGradient(src, x, y);
                sum = abs(gx) + abs(gy);
                sum = sum > 255 ? 255:sum;
                sum = sum < 0 ? 0 : sum;
                dst.at<uchar>(y,x) = sum;
            }
        }

        namedWindow("final");
        imshow("final", dst);

        namedWindow("initial");
        imshow("initial", src);

      waitKey();


    return 0;
}

 

 
پاسخ داده شده اسفند 28, 1392 بوسیله ی مصطفی ساتکی (امتیاز 16,378)   16 24 66
...