نمایش نتایج 1 تا 12 از 12

نام تاپیک: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

  1. #1
    کاربر دائمی آواتار asefy2008
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    تهران
    سن
    36
    پست
    729

    Question تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    سلام دوستان
    می خواستم بدونم کسی کلاس تشخیص دایره که از تبدیل هاف دایروی برای تشخیص دایره استفاده کرده باشه داره؟
    (نکته : حتی الامکان با سی شارپ باشه)

    در ضمن می خواستم بدونم دوستان راه بهتری دارند؟

  2. #2
    کاربر دائمی آواتار مصطفی ساتکی
    تاریخ عضویت
    اردیبهشت 1386
    محل زندگی
    www.7khatcode.com
    پست
    1,193

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    سورسش موجوده ولي تجربه ميگه كه hough circle يك روش robust براي localize كردن دايره در صفحه نيست هم بار محاسباتي بالايي داره و هم اينكه دقت مناسب رو نداره و همچنين به ميران دايره بودن blob هدف نيز خيلي حساسه.
    راه بهتر اينه كه لبه ها رو در تصوير پيدا كنيد و سپس نقاط رو با distance مشخصي نمونه برداري كنيد سپس هر سه نقطه مجاور با distance موردنظر عمود منصف رو بدست بياريد سپس نقاط تقاطع اين عمود منصف ها رو در يك accumulator انباشت كنيد مجموعه نقاط ماكزيمم در اين accumulator مجموعه اي از مراكز دايره ها موجود در صفحه هستند حالا براي اينكه fake maximum رو fade كنيد بايستي روي كل accumulator گوسين رو اعمال كنيد حالا همه نقاط صحت دارند.
    حالا از اين نقاطي كه بدست آمده شما بايستي به دنبال دايره هايي با شعاع مشخص باشيد از نقاط بدست آمده به صورت radial كليه نقاط مربوط به صفحه نمونه برداري رو كه دربازه minimum radius و maximum radius قرار دارند رو نگه داريد و بقيه نقاط رو پاك كنيد سپس به ازاي هر نقطه كليه نقاطي رو كه در عمليات فيلتر مرحله قبل رو در يك آرايه بريزيد و به صورت سيگنال باهاش رفتار كنيد حال دوباره روي اين نقاط median رو اعمال كنيد و ماكزيمم رو در اين سيگنال بدست بياريد اين maximum ميشه شعاع مدنظر شما.(نكته : چون شعاع هاي بزرگتر تعداد sample هاشون بيشتر هميشه ديگر شعاع رو محو مي كنند بهترين راه اينه كه اين شعاع ها رو با توجه به degree شون quantize كنيد و شعاعي انتخاب شه كه بتونه بيشتر 2 پي رو پوشش بده)


    namespace AForge.Imaging
    {
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Drawing.Imaging;

    /// <summary>
    /// Hough circle.
    /// </summary>
    ///
    /// <remarks>Represents circle of Hough transform.</remarks>
    ///
    public class HoughCircle : IComparable
    {
    /// <summary>
    /// Circle center's X coordinate.
    /// </summary>
    public readonly int X;

    /// <summary>
    /// Circle center's Y coordinate.
    /// </summary>
    public readonly int Y;

    /// <summary>
    /// Circle's radius.
    /// </summary>
    public readonly int Radius;

    /// <summary>
    /// Line's absolute intensity.
    /// </summary>
    public readonly short Intensity;

    /// <summary>
    /// Line's relative intensity.
    /// </summary>
    public readonly double RelativeIntensity;

    /// <summary>
    /// Initializes a new instance of the <see cref="HoughCircle"/> class.
    /// </summary>
    ///
    /// <param name="x">Circle's X coordinate.</param>
    /// <param name="y">Circle's Y coordinate.</param>
    /// <param name="radius">Circle's radius.</param>
    /// <param name="intensity">Circle's absolute intensity.</param>
    /// <param name="relativeIntensity">Circle's relative intensity.</param>
    ///
    public HoughCircle( int x, int y, int radius, short intensity, double relativeIntensity )
    {
    X = x;
    Y = y;
    Radius = radius;
    Intensity = intensity;
    RelativeIntensity = relativeIntensity;
    }

    /// <summary>
    /// Compare the object with another instance of this class.
    /// </summary>
    ///
    /// <param name="value">Object to compare with.</param>
    ///
    /// <returns><para>A signed number indicating the relative values of this instance and <b>value</b>: 1) greater than zero -
    /// this instance is greater than <b>value</b>; 2) zero - this instance is equal to <b>value</b>;
    /// 3) greater than zero - this instance is less than <b>value</b>.</para>
    /// <para><note>The sort order is descending.</note></para></returns>
    ///
    public int CompareTo( object value )
    {
    return ( -Intensity.CompareTo( ( (HoughCircle) value ).Intensity ) );
    }
    }

    /// <summary>
    /// Hough circle transformation.
    /// </summary>
    ///
    /// <remarks><para>Hough circle transformation allows to detect circles in image.</para>
    /// <para>Sample usage:</para>
    /// <code>
    /// HoughCircleTransformation circleTransform = new HoughCircleTransformation( );
    /// // apply Hough circle transform
    /// circleTransform.ProcessImage( sourceImage );
    /// Bitmap houghCirlceImage = circleTransform.ToBitmap( );
    /// // get circles using relative intensity
    /// HoughCircle[] circles = circleTransform.GetCirclesByRelativeIntensity( 0.5 );
    ///
    /// foreach ( HoughCircle circle in circles )
    /// {
    /// // ..
    /// }
    ///
    /// </code>
    /// </remarks>
    ///
    public class HoughCircleTransformation
    {
    // circle radius to detect
    private int radiusToDetect;

    // Hough map
    private short[,] houghMap;
    private short maxMapIntensity = 0;

    // Hough map's width and height
    private int width;
    private int height;

    private int localPeakRadius = 4;
    private short minCircleIntensity = 10;
    private ArrayList circles = new ArrayList( );

    /// <summary>
    /// Minimum circles's intensity in Hough map to recognize a circle.
    /// </summary>
    ///
    /// <remarks><para>The value sets minimum intensity level for a circle. If a value in Hough
    /// map has lower intensity, then it is not treated as a circle.</para>
    /// <para>Default value is <b>10</b>.</para></remarks>
    ///
    public short MinCircleIntensity
    {
    get { return minCircleIntensity; }
    set { minCircleIntensity = value; }
    }

    /// <summary>
    /// Radius for searching local peak value.
    /// </summary>
    ///
    /// <remarks><para>The value determines radius around a map's value, which is analyzed to determine
    /// if the map's value is a maximum in specified area.</para>
    /// <para>Default value is <b>4</b>. Minimum value is <b>1</b>. Maximum value is <b>10</b>.</para></remarks>
    ///
    public int LocalPeakRadius
    {
    get { return localPeakRadius; }
    set { localPeakRadius = Math.Max( 1, Math.Min( 10, value ) ); }
    }

    /// <summary>
    /// Maximum found intensity in Hough map.
    /// </summary>
    ///
    public short MaxIntensity
    {
    get { return maxMapIntensity; }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="HoughCircleTransformation"/> class.
    /// </summary>
    ///
    public HoughCircleTransformation( int radiusToDetect )
    {
    this.radiusToDetect = radiusToDetect;
    }

    /// <summary>
    /// Found circles count.
    /// </summary>
    ///
    public int CirclesCount
    {
    get { return circles.Count; }
    }

    /// <summary>
    /// Process an image building Hough map.
    /// </summary>
    ///
    /// <param name="image">Source image to process.</param>
    ///
    public void ProcessImage( Bitmap image )
    {
    // check image format
    if ( image.PixelFormat != PixelFormat.Format8bppIndexed )
    throw new ArgumentException( "Pixel format of source image should be 8 bpp indexed" );

    // lock source image
    BitmapData imageData = image.LockBits(
    new Rectangle( 0, 0, image.Width, image.Height ),
    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed );

    // process the image
    ProcessImage( imageData );

    // unlock image
    image.UnlockBits( imageData );
    }

    /// <summary>
    /// Process an image building Hough map.
    /// </summary>
    ///
    /// <param name="imageData">Source image data to process.</param>
    ///
    public void ProcessImage( BitmapData imageData )
    {
    if ( imageData.PixelFormat != PixelFormat.Format8bppIndexed )
    throw new ArgumentException( "Pixel format of source image should be 8 bpp indexed" );

    // get source image size
    width = imageData.Width;
    height = imageData.Height;

    int srcOffset = imageData.Stride - width;

    // allocate Hough map of the same size like image
    houghMap = new short[height, width];

    // do the job
    unsafe
    {
    byte* src = (byte*) imageData.Scan0.ToPointer( );

    // for each row
    for ( int y = 0; y < height; y++ )
    {
    // for each pixel
    for ( int x = 0; x < width; x++, srC++‎ )
    {
    if ( *src != 0 )
    {
    DrawHoughCircle( x, y );
    }
    }
    src += srcOffset;
    }
    }

    // find max value in Hough map
    maxMapIntensity = 0;
    for ( int i = 0; i < height; i++ )
    {
    for ( int j = 0; j < width; j++ )
    {
    if ( houghMap[i, j] > maxMapIntensity )
    {
    maxMapIntensity = houghMap[i, j];
    }
    }
    }

    CollectCircles( );
    }

    /// <summary>
    /// onvert Hough map to bitmap.
    /// </summary>
    ///
    /// <returns>Returns a bitmap, which shows Hough map.</returns>
    ///
    public Bitmap ToBitmap( )
    {
    // check if Hough transformation was made already
    if ( houghMap == null )
    {
    throw new ApplicationException( "Hough transformation was not done yet" );
    }

    int width = houghMap.GetLength( 1 );
    int height = houghMap.GetLength( 0 );

    // create new image
    Bitmap image = AForge.Imaging.Image.CreateGrayscaleImage( width, height );

    // lock destination bitmap data
    BitmapData imageData = image.LockBits(
    new Rectangle( 0, 0, width, height ),
    ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed );

    int offset = imageData.Stride - width;
    float scale = 255.0f / maxMapIntensity;

    // do the job
    unsafe
    {
    byte* dst = (byte*) imageData.Scan0.ToPointer( );

    for ( int y = 0; y < height; y++ )
    {
    for ( int x = 0; x < width; x++, dst++ )
    {
    *dst = (byte) System.Math.Min( 255, (int) ( scale * houghMap[y, x] ) );
    }
    dst += offset;
    }
    }

    // unlock destination images
    image.UnlockBits( imageData );

    return image;
    }

    /// <summary>
    /// Get specified amount of circles with highest intensity.
    /// </summary>
    ///
    /// <param name="count">Amount of circles to get.</param>
    ///
    /// <returns>Returns arrary of most intesive circles. If there are no circles detected,
    /// <b>null</b> is returned.</returns>
    ///
    public HoughCircle[] GetMostIntensiveCircles( int count )
    {
    // lines count
    int n = Math.Min( count, circles.Count );

    if ( n == 0 )
    return null;

    // result array
    HoughCircle[] dst = new HoughCircle[n];
    circles.CopyTo( 0, dst, 0, n );

    return dst;
    }

    /// <summary>
    /// Get circles with relative intensity higher then specified value.
    /// </summary>
    ///
    /// <param name="minRelativeIntensity">Minimum relative intesity of circles.</param>
    ///
    /// <returns>Returns array of circles. If there are no circles detected,
    /// <b>null</b> is returned.</returns>
    ///
    public HoughCircle[] GetCirclesByRelativeIntensity( double minRelativeIntensity )
    {
    int count = 0, n = circles.Count;

    while ( ( count < n ) && ( ( (HoughCircle) circles[count] ).RelativeIntensity >= minRelativeIntensity ) )
    count++;

    return GetMostIntensiveCircles( count );
    }


    // Collect circles with intesities greater or equal then specified
    private void CollectCircles( )
    {
    short intensity;
    bool foundGreater;

    // clean circles collection
    circles.Clear( );

    // for each Y coordinate
    for ( int y = 0; y < height; y++ )
    {
    // for each X coordinate
    for ( int x = 0; x < width; x++ )
    {
    // get current value
    intensity = houghMap[y, x];

    if ( intensity < minCircleIntensity )
    continue;

    foundGreater = false;

    // check neighboors
    for ( int ty = y - localPeakRadius, tyMax = y + localPeakRadius; ty < tyMax; ty++ )
    {
    // continue if the coordinate is out of map
    if ( ty < 0 )
    continue;
    // break if it is not local maximum or coordinate is out of map
    if ( ( foundGreater == true ) || ( ty >= height ) )
    break;

    for ( int tx = x - localPeakRadius, txMax = x + localPeakRadius; tx < txMax; tx++ )
    {
    // continue or break if the coordinate is out of map
    if ( tx < 0 )
    continue;
    if ( tx >= width )
    break;

    // compare the neighboor with current value
    if ( houghMap[ty, tx] > intensity )
    {
    foundGreater = true;
    break;
    }
    }
    }

    // was it local maximum ?
    if ( !foundGreater )
    {
    // we have local maximum
    circles.Add( new HoughCircle( x, y, radiusToDetect, intensity, (double) intensity / maxMapIntensity ) );
    }
    }
    }

    circles.Sort( );
    }

    // Draw Hough circle:
    // http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html
    //
    // TODO: more optimizations of circle drawing could be done.
    //
    private void DrawHoughCircle( int xCenter, int yCenter )
    {
    int x = 0;
    int y = radiusToDetect;
    int p = ( 5 - radiusToDetect * 4 ) / 4;

    SetHoughirclePoints( xCenter, yCenter, x, y );

    while ( x < y )
    {
    x++;
    if ( p < 0 )
    {
    p += 2 * x + 1;
    }
    else
    {
    y--;
    p += 2 * ( x - y ) + 1;
    }
    SetHoughirclePoints( xCenter, yCenter, x, y );
    }
    }

    // Set circle points
    private void SetHoughirclePoints( int cx, int cy, int x, int y )
    {
    if ( x == 0 )
    {
    SetHoughPoint( cx, cy + y );
    SetHoughPoint( cx, cy - y );
    SetHoughPoint( cx + y, cy );
    SetHoughPoint( cx - y, cy );
    }
    else if ( x == y )
    {
    SetHoughPoint( cx + x, cy + y );
    SetHoughPoint( cx - x, cy + y );
    SetHoughPoint( cx + x, cy - y );
    SetHoughPoint( cx - x, cy - y );
    }
    else if ( x < y )
    {
    SetHoughPoint( cx + x, cy + y );
    SetHoughPoint( cx - x, cy + y );
    SetHoughPoint( cx + x, cy - y );
    SetHoughPoint( cx - x, cy - y );
    SetHoughPoint( cx + y, cy + x );
    SetHoughPoint( cx - y, cy + x );
    SetHoughPoint( cx + y, cy - x );
    SetHoughPoint( cx - y, cy - x );
    }
    }

    // Set point
    private void SetHoughPoint( int x, int y )
    {
    if ( ( x >= 0 ) && ( y >= 0 ) && ( x < width ) && ( y < height ) )
    {
    houghMap[y, x]++;
    }
    }
    }

    }

  3. #3
    کاربر دائمی آواتار asefy2008
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    تهران
    سن
    36
    پست
    729

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    چند سوال داشتم :
    1.منظور از با distance مشخص نمونه برداری کنیم یعنی چی؟(فرض کنید عکس لبه یابی شده را داریم حالا باید چطوری این کار را اجام بدیم)
    2. منظور از سه نقطه کنار هم، هم در راستای محور xها و هم در راستای محور yها هست دیگه و همچنین مورب رو هم شامل میشه؟
    3. fake maximum و fade یعنی چی ؟
    4.
    حالا براي اينكه fake maximum رو fade كنيد بايستي روي كل accumulator گوسين رو اعمال كنيد حالا همه نقاط صحت دارند.
    اگه میشه در مورد این جمله بیشتر توضیح بدید؟

  4. #4
    کاربر دائمی آواتار مصطفی ساتکی
    تاریخ عضویت
    اردیبهشت 1386
    محل زندگی
    www.7khatcode.com
    پست
    1,193

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    جواب اول : sampling یا نمونه برداری یعنی اینکه از کل نمونه ها ، نمونه خاصی را انتخاب کنیم در اینجا لبه های متوالی که داریم رو با فواصل مشخص نمونه برداری می کنیم.
    جواب دوم : نقاط مجاور یعنی که نقاطی که در یک مسیر بدون فاصله پشت سرهم قرار گرفتن در ضمن نقاطی که در راستای x یا y قرار دارند یا در زاویای K*pi/4 قرار دارند جز همسایگی محسوب نمیشن.
    جواب سوم : یعنی اینکه maximum هایی که ساختگی هستند و صحت ندارند حذف می شن
    جواب چهارم : از این روش جهت حذف نویز استفاده میشه

  5. #5
    کاربر دائمی آواتار asefy2008
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    تهران
    سن
    36
    پست
    729

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    ممنون از جوابتون
    جواب اول : sampling یا نمونه برداری یعنی اینکه از کل نمونه ها ، نمونه خاصی را انتخاب کنیم در اینجا لبه های متوالی که داریم رو با فواصل مشخص نمونه برداری می کنیم.
    منظور از لبه های متواالی که داریم با فواصل مشخص نمونه برداری می کنیم این هست که مثلا در لبه ها 5 یا 10 سلول متوالی را به عنوان یک نمونه انتخاب می کنیم؟

  6. #6
    کاربر دائمی آواتار مصطفی ساتکی
    تاریخ عضویت
    اردیبهشت 1386
    محل زندگی
    www.7khatcode.com
    پست
    1,193

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    بله sampling در واقع به همین معناست

  7. #7
    کاربر دائمی آواتار asefy2008
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    تهران
    سن
    36
    پست
    729

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    ممون
    در قطعه کدی که قرار دادید من از قطعه کد زیر برای اجرا اون و تشخیص دایره استفاده کردم :

    HoughCircleTransformation circleTransform = new HoughCircleTransformation( 35 ); // apply Hough circle transform circleTransform.ProcessImage( sourceImage ); Bitmap houghCirlceImage = circleTransform.ToBitmap( ); // get circles using relative intensity HoughCircle[] circles = circleTransform.GetCirclesByRelativeIntensity( 0.5 ); foreach ( HoughCircle circle in circles ) { // ... }


    ولی در processimage از فرمت عکس ایراد می گیره علتش چیه و چطور میشه رفعش کرد.

    نکته : من یک تغییراتی تو اون قسمت دادم و درست شد ولی به هیچ عنوان نمی تونه دایره رو درست تشخیص بده من شکل داخل سایت aforge رو دادم بهش ولی اون جواب رو بهم نداد در صورتی که برای مثالی که خود سایت aforge داده درست کار می کنه(من مثال خود سایت رو دانلود کردم و پایین قرار دادم).

    اینم کتغییراتی که من در کد دادم :
    public void ProcessImage( Bitmap image )
    {
    // check image format
    if ( image.PixelFormat != PixelFormat.Format32bppArgb )
    throw new ArgumentException( "Pixel format of source image should be 8 bpp indexed" );

    // lock source image
    BitmapData imageData = image.LockBits(
    new Rectangle( 0, 0, image.Width, image.Height ),
    ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );

    // process the image
    ProcessImage( imageData );

    // unlock image
    image.UnlockBits( imageData );
    }
    فایل های ضمیمه فایل های ضمیمه

  8. #8
    کاربر دائمی آواتار مصطفی ساتکی
    تاریخ عضویت
    اردیبهشت 1386
    محل زندگی
    www.7khatcode.com
    پست
    1,193

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    من اگر توجه کرده باشید در پست شماره 2 به شما عرض کردم که hough circle ط یک localizer خوبی نیست در همون پست برای شما نحوه پیاده یازی circle finder رو توضیح دادم من خودم به شخصه در کارهام از چندین نوع circle finder استفاده می کنم که توسط خودم پیاده شده و طرحش هم از خودم بوده با توجه به شرایط شما می تونید rule هایی رو به هر کدام از circle finder ها اعمال کنید که در همون زمینه مشخص جوابهای robust ی رو به شما میده

  9. #9
    کاربر دائمی آواتار asefy2008
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    تهران
    سن
    36
    پست
    729

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    با تشکر از شما
    می خواستم ببینم نمونه کد تبدیل هاف دایروی رو با متلب دارید(یا هر کدی با متلب که بتوننه دایره رو تشخیص بده)؟

    در ضمن ممنون از توضیحات قبلیتون که واقعا کمکم کرد وتونستم یک راه جدید برای کارم پیداکنم.

  10. #10
    کاربر دائمی آواتار مصطفی ساتکی
    تاریخ عضویت
    اردیبهشت 1386
    محل زندگی
    www.7khatcode.com
    پست
    1,193

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    خواهش می کنم.
    من با C++‎ کار می کنم ولی به c اگر بخاید می تونم راهنمایی تون کنم

  11. #11
    کاربر دائمی آواتار asefy2008
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    تهران
    سن
    36
    پست
    729

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    ممنون میشم اگه کمک بفرمایید.
    فکر کنم بالاخره باید برم سمت C++‎‎ اکثر کدها چه در اینترنت و چه دوستان می فرماین به متلب و سی هست.

    من سرانجام تونستم پروژه تشخیص هویت از طریق عنبیه رو تکمیل کنم ولی بزرگترین مشکلش کندی در پیدا کردن دایره که واقعا برنامه رو کند کرد.(البته دایره داخلی رو با کمک های شما خیلی سریع پیدا می کنه.)

  12. #12

    نقل قول: تشخیص دایره در تصویر با استفاده از تبدیل هاف دایروی

    سلام به دوستان
    كسي برنامه تشخيص دايره با متلب را داره ؟

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •