الگوریتم sobel

کد الگوریتم سوبل – متد سوبل لبه ها را با استفاده از تخمین زدن مشتق پیدا می کند، که لبه ها را در آن نقاطی بر می گرداند که گرادیان تصویر I ، max است. پیشنهاد می کنیم جهت آشنایی با الگوریتم های لبه یابی، مطلب «الگوریتم های لبه یابی و انواع آن» را مشاهده نمایید. در فیلتر سوبل دو ماسک به صورت زیر وجود دارد:

ماسک سوبل عمودی         ماسک سوبل افقی

ماسک سوبل افقی بیشتر لبه هاي افقی را مشخص میکند و ماسک سوبل عمودي،لبه هاي عمودي را مشخص میکند.

براي مشخص شدن کلیه لبه ها:
اگر Gو Gy تصاویر فیلتر شده به وسیله ماسک افقی و عمودي باشند، آنگاه تصویر  فرمول الگوریتم سوبل    لبه هاي تصویر را بهتر نشان میدهد. روال فوق به عملگر یا الگورریتم سوبل موسوم است.
در عمل، به منظور کاهش هزینه محاسبات، به جاي  فرمول الگوریتم سوبل  میتوان از تقریب [Gx] + [Gy] استفاده میشود. توجه شود که نتیجه این دو فرمول تقریبا یکسان است ولی فرمول دوم با هزینه کمتري قابل محاسبه می باشد.

تأثیر عملگر سوبل بر لبه یابی تصاویر

 

کد الگوریتم سوبل( Sobel ) در Matlab:

 

clc; clear; close all; warning off; 

I=imread('lena.bmp');
I=im2double(I);
I=imnoise(I, 'gaussian', 0, 0.001);
figure(1);
imshow(I);title('org img');

[height width R]=size(I);

for i=2:height-1
    for j=2:width-1
        Dx(i,j)=[I(i+1,j-1)-I(i-1,j-1)]+2*[I(i+1,j)-I(i-1,j)]+[I(i+1,j+1)-I(i-1,j+1)];
        Dy(i,j)=[I(i-1,j+1)-I(i-1,j-1)]+2*[I(i,j+1)-I(i,j-1)]+[I(i+1,j+1)-I(i+1,j-1)];
        S(i,j)=sqrt(Dx(i,j)^2+Dy(i,j)^2);
        if Dx(i,j)<1
            Dx(i,j)=0;
        else Dx(i,j)=1;
        end
        if Dy(i,j)<1
            Dy(i,j)=0;
        else Dy(i,j)=1;
        end
    end
end
figure(2);
imshow(Dx,[]);

figure(3);
imshow(Dy,[]);

for i=1:255
    for j=1:255
       if (S(i,j)<1)
            S(i,j)=0;
        else S(i,j)=1;
        end
    end
end
figure(4);
imshow(S,[]);
دانلود کد فوق از طریق لینک زیر:

الگوریتم سوبل به زبان متلب

رمز فایل : behsanandish.com


 

کد الگوریتم سوبل( Sobel ) در #C:

۱٫کد برای فیلتر کانولوشن: بخش اول این تابع برای گرفتن اطلاعات تصویر و ذخیره آن به آرایه اختصاص داده شده است.

 

private static Bitmap ConvolutionFilter(Bitmap sourceImage, 
    double[,] xkernel, 
    double[,] ykernel, double factor = 1, int bias = 0, bool grayscale = false)
{

    //Image dimensions stored in variables for convenience
    int width = sourceImage.Width;
    int height = sourceImage.Height;

     //Lock source image bits into system memory
    BitmapData srcData = sourceImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

     //Get the total number of bytes in your image - 32 bytes per pixel x image width x image height -> for 32bpp images
    int bytes = srcData.Stride * srcData.Height;

     //Create byte arrays to hold pixel information of your image
    byte[] pixelBuffer = new byte[bytes];
    byte[] resultBuffer = new byte[bytes];

     //Get the address of the first pixel data
    IntPtr srcScan0 = srcData.Scan0;

     //Copy image data to one of the byte arrays
    Marshal.Copy(srcScan0, pixelBuffer, 0, bytes);

    //Unlock bits from system memory -> we have all our needed info in the array
    sourceImage.UnlockBits(srcData);

 

۲٫کد تبدیل سیاه و سفید: از آنجایی که اپراتور Sobel اغلب برای تصاویر سیاه و سفید استفاده می شود، در اینجا یک کد برای تبدیل به سیاه و سفید است که توسط پارامتر boolean شما می توانید انتخاب کنید تبدیل کردن را یا نه.

 

//Convert your image to grayscale if necessary
if (grayscale == true)
{
    float rgb = 0;
    for (int i = 0; i < pixelBuffer.Length; i += 4)
    {
        rgb = pixelBuffer[i] * .21f;
        rgb += pixelBuffer[i + 1] * .71f;
        rgb += pixelBuffer[i + 2] * .071f;
        pixelBuffer[i] = (byte)rgb;
        pixelBuffer[i + 1] = pixelBuffer[i];
        pixelBuffer[i + 2] = pixelBuffer[i];
        pixelBuffer[i + 3] = 255;
    }
}

 

۳٫کد برای تنظیم متغیرهای مورد استفاده در فرآیند کانولوشن:

 

/Create variable for pixel data for each kernel
double xr = 0.0;
double xg = 0.0;
double xb = 0.0;
double yr = 0.0;
double yg = 0.0;
double yb = 0.0;
double rt = 0.0;
double gt = 0.0;
double bt = 0.0;

//This is how much your center pixel is offset from the border of your kernel
//Sobel is 3x3, so center is 1 pixel from the kernel border
int filterOffset = 1;
int calcOffset = 0;
int byteOffset = 0;

//Start with the pixel that is offset 1 from top and 1 from the left side
//this is so entire kernel is on your image
for (int OffsetY = filterOffset; OffsetY < height - filterOffset; OffsetY++)
{
    for (int OffsetX = filterOffset; OffsetX < width - filterOffset; OffsetX++)
    {
        //reset rgb values to 0
        xr = xg = xb = yr = yg = yb = 0;
        rt = gt = bt = 0.0;

        //position of the kernel center pixel
        byteOffset = OffsetY * srcData.Stride + OffsetX * 4;

 

۴٫ اعمال کانولوشن هسته به پیکسل فعلی:

 

//kernel calculations
for (int filterY = -filterOffset; filterY <= filterOffset; filterY++)
{
for (int filterX = -filterOffset; filterX <= filterOffset; filterX++)
{
calcOffset = byteOffset + filterX * 4 + filterY * srcData.Stride;
xb += (double)(pixelBuffer[calcOffset]) * xkernel[filterY + filterOffset, filterX + filterOffset];
xg += (double)(pixelBuffer[calcOffset + 1]) * xkernel[filterY + filterOffset, filterX + filterOffset];
xr += (double)(pixelBuffer[calcOffset + 2]) * xkernel[filterY + filterOffset, filterX + filterOffset];
yb += (double)(pixelBuffer[calcOffset]) * ykernel[filterY + filterOffset, filterX + filterOffset];
yg += (double)(pixelBuffer[calcOffset + 1]) * ykernel[filterY + filterOffset, filterX + filterOffset];
yr += (double)(pixelBuffer[calcOffset + 2]) * ykernel[filterY + filterOffset, filterX + filterOffset];
}
}

//total rgb values for this pixel
bt = Math.Sqrt((xb * xb) + (yb * yb));
gt = Math.Sqrt((xg * xg) + (yg * yg));
rt = Math.Sqrt((xr * xr) + (yr * yr));

//set limits, bytes can hold values from 0 up to 255;
if (bt > 255) bt = 255;
else if (bt < 0) bt = 0;
if (gt > 255) gt = 255;
else if (gt < 0) gt = 0;
if (rt > 255) rt = 255;
else if (rt < 0) rt = 0;

//set new data in the other byte array for your image data
resultBuffer[byteOffset] = (byte)(bt);
resultBuffer[byteOffset + 1] = (byte)(gt);
resultBuffer[byteOffset + 2] = (byte)(rt);
resultBuffer[byteOffset + 3] = 255;
}
}

 

۵٫ کد خروجی تصویر پردازش شده:

 

//Create new bitmap which will hold the processed data
    Bitmap resultImage = new Bitmap(width, height);

    //Lock bits into system memory
    BitmapData resultData = resultImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

    //Copy from byte array that holds processed data to bitmap
    Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length);

    //Unlock bits from system memory
    resultImage.UnlockBits(resultData);

    //Return processed image
    return resultImage;
}

 

۶٫ کد برای هسته سوبل:

 

//Sobel operator kernel for horizontal pixel changes
private static double[,] xSobel
{
    get
    {
        return new double[,]
        {
            { -۱, ۰, ۱ },
            { -۲, ۰, ۲ },
            { -۱, ۰, ۱ }
        };
    }
}

//Sobel operator kernel for vertical pixel changes
private static double[,] ySobel
{
    get
    {
        return new double[,]
        {
            {  ۱,  ۲,  ۱ },
            {  ۰,  ۰,  ۰ },
            { -۱, -۲, -۱ }
        };
    }
}

 

همه این کد در اینجا موجود است (پروژه با ویژوال استودیو ۲۰۱۵ ایجاد شد):

SobelOperatorInC#

رمز فایل : behsanandish.com

 

کد الگوریتم sobel در #C

 


 

کد الگوریتم سوبل( Sobel ) در ++C:

در ادامه دو کد برای الگوریتم Sobel  در ++C آماده کردیم:

۱٫

 

#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) +
                ۲*image.at<uchar>(y, x-1) +
                 image.at<uchar>(y+1, x-1) -
                  image.at<uchar>(y-1, x+1) -
                   ۲*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) +
                ۲*image.at<uchar>(y-1, x) +
                 image.at<uchar>(y-1, x+1) -
                  image.at<uchar>(y+1, x-1) -
                   ۲*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;
}

 

دانلود کد فوق از طریق لینک زیر:

Sobel in C++-Code1

رمز فایل : behsanandish.com

 

۲٫

 

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSobelEdgeDetectionImageFilter.h"

int main( int argc, char* argv[] )
{
  if( argc != 3 )
    {
    std::cerr << "Usage: "<< std::endl;
    std::cerr << argv[0];
    std::cerr << "<InputFileName> <OutputFileName>";
    std::cerr << std::endl;
    return EXIT_FAILURE;
    }

  constexpr unsigned int Dimension = 2;

  using InputPixelType = unsigned char;
  using InputImageType = itk::Image< InputPixelType, Dimension >;

  using ReaderType = itk::ImageFileReader< InputImageType >;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  using OutputPixelType = float;
  using OutputImageType = itk::Image< OutputPixelType, Dimension >;

  using FilterType = itk::SobelEdgeDetectionImageFilter< InputImageType, OutputImageType >;
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput( reader->GetOutput() );

  using WriterType = itk::ImageFileWriter< OutputImageType >;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( argv[2] );
  writer->SetInput( filter->GetOutput() );

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}

 

دانلود کد فوق از طریق لینک زیر:

Sobel in C++-Code2

رمز فایل : behsanandish.com

 


کد الگوریتم سوبل( Sobel ) در C:

 

/* sobel.c */
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include "mypgm.h"

void sobel_filtering( )
     /* Spatial filtering of image data */
     /* Sobel filter (horizontal differentiation */
     /* Input: image1[y][x] ---- Outout: image2[y][x] */
{
  /* Definition of Sobel filter in horizontal direction */
  int weight[3][3] = {{ -1,  ۰,  ۱ },
      { -۲,  ۰,  ۲ },
      { -۱,  ۰,  ۱ }};
  double pixel_value;
  double min, max;
  int x, y, i, j;  /* Loop variable */

  /* Maximum values calculation after filtering*/
  printf("Now, filtering of input image is performed\n\n");
  min = DBL_MAX;
  max = -DBL_MAX;
  for (y = 1; y < y_size1 - 1; y++) {
    for (x = 1; x < x_size1 - 1; x++) {
      pixel_value = 0.0;
      for (j = -1; j <= 1; j++) {
    for (i = -1; i <= 1; i++) {
      pixel_value += weight[j + 1][i + 1] * image1[y + j][x + i];
    }
      }
      if (pixel_value < min) min = pixel_value;
      if (pixel_value > max) max = pixel_value;
    }
  }
  if ((int)(max - min) == 0) {
    printf("Nothing exists!!!\n\n");
    exit(1);
  }

  /* Initialization of image2[y][x] */
  x_size2 = x_size1;
  y_size2 = y_size1;
  for (y = 0; y < y_size2; y++) {
    for (x = 0; x < x_size2; x++) {
      image2[y][x] = 0;
    }
  }
  /* Generation of image2 after linear transformtion */
  for (y = 1; y < y_size1 - 1; y++) {
    for (x = 1; x < x_size1 - 1; x++) {
      pixel_value = 0.0;
      for (j = -1; j <= 1; j++) {
    for (i = -1; i <= 1; i++) {
      pixel_value += weight[j + 1][i + 1] * image1[y + j][x + i];
    }
      }
      pixel_value = MAX_BRIGHTNESS * (pixel_value - min) / (max - min);
      image2[y][x] = (unsigned char)pixel_value;
    }
  }
}

main( )
{
  load_image_data( );   /* Input of image1 */ 
  sobel_filtering( );   /* Sobel filter is applied to image1 */
  save_image_data( );   /* Output of image2 */
  return 0;
}
دانلود کد فوق از طریق لینک زیر:

Sobel in C

رمز فایل : behsanandish.com


 

کد الگوریتم سوبل( Sobel ) در Visual Basic:

 

Private Sub bEdge_Click(sender As Object, e As EventArgs) _
Handles bEdge.Click

'Sobel Edge'
Dim tmpImage As Bitmap = New Bitmap(picOriginal.Image)
Dim bmpImage As Bitmap = New Bitmap(picOriginal.Image)

Dim intWidth As Integer = tmpImage.Width
Dim intHeight As Integer = tmpImage.Height

Dim intOldX As Integer(,) = New Integer(,) {{-1, 0, 1}, _
{-۲, ۰, ۲}, {-۱, ۰, ۱}}
Dim intOldY As Integer(,) = New Integer(,) {{1, 2, 1}, _
{۰, ۰, ۰}, {-۱, -۲, -۱}}

Dim intR As Integer(,) = New Integer(intWidth - 1, _
intHeight - 1) {}
Dim intG As Integer(,) = New Integer(intWidth - 1, _
intHeight - 1) {}
Dim intB As Integer(,) = New Integer(intWidth - 1, _
intHeight - 1) {}

Dim intMax As Integer = 128 * 128

For i As Integer = 0 To intWidth - 1

For j As Integer = 0 To intHeight - 1

intR(i, j) = tmpImage.GetPixel(i, j).R
intG(i, j) = tmpImage.GetPixel(i, j).G
intB(i, j) = tmpImage.GetPixel(i, j).B

Next

Next

Dim intRX As Integer = 0
Dim intRY As Integer = 0
Dim intGX As Integer = 0
Dim intGY As Integer = 0
Dim intBX As Integer = 0
Dim intBY As Integer = 0

Dim intRTot As Integer
Dim intGTot As Integer
Dim intBTot As Integer

For i As Integer = 1 To tmpImage.Width - 1 - 1

For j As Integer = 1 To tmpImage.Height - 1 - 1

intRX = 0
intRY = 0
intGX = 0
intGY = 0
intBX = 0
intBY = 0

intRTot = 0
intGTot = 0
intBTot = 0

For width As Integer = -1 To 2 - 1

For height As Integer = -1 To 2 - 1

intRTot = intR(i + height, j + width)
intRX += intOldX(width + 1, height + 1) * intRTot
intRY += intOldY(width + 1, height + 1) * intRTot

intGTot = intG(i + height, j + width)
intGX += intOldX(width + 1, height + 1) * intGTot
intGY += intOldY(width + 1, height + 1) * intGTot

intBTot = intB(i + height, j + width)
intBX += intOldX(width + 1, height + 1) * intBTot
intBY += intOldY(width + 1, height + 1) * intBTot

Next

Next

If intRX * intRX + intRY * intRY > intMax OrElse
intGX * intGX + intGY * intGY > intMax OrElse
intBX * intBX + intBY * intBY > intMax Then

bmpImage.SetPixel(i, j, Color.Black)

Else

bmpImage.SetPixel(i, j, Color.Transparent)

End If

Next

Next

picModified.Image = bmpImage

End Sub
دانلود کد فوق از طریق لینک زیر:

Sobel in VB

رمز فایل : behsanandish.com

 

کد الگوریتم sobel در VB

 


 

پیشنهاد می کنیم جهت آشنایی با الگوریتم های لبه یابی، مطلب «الگوریتم های لبه یابی و انواع آن» را مشاهده نمایید.

 

شناسایی حروف توسط شبکه های عصبی

تو این مطلب می خواهیم بصورت عملی از شبکه های عصبی استفاده کنیم! واقعا خیلی جالبه می خوایم به کامپیوتر سه تا حرف الفبای انگلیسی رو یاد بدیم.
نکته ی جالب تر این هست که حتی به کامپیوتر نمی گیم هر کدوم از حرف ها چی هستن! فقط بهش می گیم که این ها سه حرف مختلف هستند! و کامپیوتر خودش تشخیص می ده هر کدوم متعلق به کدوم گروه هست! به این نوع طبقه بندی اصطلاحا Unsupervised میگویند.

سوال : به نظر میرسه باید توی مثال هامون به کامپیوتر بگیم مثلا این A هست و این B هست!
جواب : اون هم نوعی یادگیری هست که بهش اصطلاحا Supervised می گن. اما توی این مثال حالت جالب تر یعنی Unsupervised رو می خوایم بررسی کنیم. به این صورت که فقط به کامپیوتر می گیم ۳ دسته وجود داره و براش چندین مثال می زنیم و خودش مثال ها رو توی ۳ دسته قرار می ده! در نهایت ما مثلا می تونیم بگیم همه ی مثال هایی که در دسته ی دوم قرار گرفتن A هستند.
شاید جالب باشه بدونید گوگل هم برای دسته بندی اطلاعات از همچین روشی استفاده می کنه! البته کمی پیشرفته تر. مثلا ۱۰۰ متن اقتصادی و ۱۰۰ متن ورزشی به کامپیوتر میده و از کامپیوتر می خواد اونها رو به ۲ بخش تقسیم بندی بکنه! ورودی لغت های اون متن ها هستند. “

ابزار مورد نیاز
برای این که شروع کنیم به چند مورد نیاز داریم:

  1. در مورد هوش مصنوعی و شبکه های عصبی یکم اطلاعات داشته باشید.
  2. برنامه ای برای تولید الگو که ورودی شبکه ی عصبی ما خواهد بود. این برنامه رو میتونید از اینجا تهیه کنید.
  3. نرم افزار JOONE Editor. عبارت JOONE مخفف Java Object Oriented Neural Engine هست. که یک ابزار قدرت مند برای بوجود آوردن و آموزش انواع شبکه های عصبی در Java هست. توی این آموزش ما از ویرایشگر این ابزار استفاده می کنیم که محیطی گرافیکی برای تولید شبکه های عصبی داره و کار با اون بسیار ساده هست. این ابزار از اینجا قابل دریافت هست. بدیهیه که برای نصب این ابزار ابتدا باید جاوا روی کامپیوتر شما نصب باشه.
  4. کمی پشتکار و حوصله.

لینک جایگزین برای دانلود JOONE Editor:
https://sourceforge.net/projects/joone/files/

حالا می خوایم یک سری الگو تولید کنیم. الگو همون مثال هایی هست که گفتیم برای کامپیوتر می زنیم تا بتونه یاد بگیره.
برای این کار از برنامه ای که در شماره ی ۲ ابزارها معرفی کردم استفاده می کنیم. این برنامه خیلی ساده کار می کنه و فقط الگو ها رو از حالت تصویری به ۰ و ۱ تبدیل می کنه.
روش کار به این صورت هست که اول تصویر رو به یک ماتریس ۸ در ۸ تقسیم می کنه. یعنی ۶۴ قسمت. وقتی دکمه ی سمت چپ ماوس پایینه در صورتی که ماوس از هر کدوم از اون ۶۴ بخش رد بشه اون بخش رو داخل ماتریس علامت گذاری می کنه (مقدار اون قسمت رو True می کنه). وقتی دکمه ی Learn زده می شه برنامه مقدار تمام قسمت ها رو از بالا به پایین داخل یک فایل ذخیره می کنه. مقدار هر قسمت می تونه ۰ یا False و ۱ یا True باشه. ”
در صورتی که سورس این برنامرو خواستید کافیه توی بخش نظرات بگید تا براتون میل کنم.
کار با این برنامه خیلی آسون هست همونطور که توی شکل مشخصه.

کافیه الگویی که دوست دارید رو داخل فضای سفید بکشید و دکمه ی Learn رو بزنید. Textbox پایینی برای تغییر دادن آدرس فایلی هست که اطلاعات توی اون ذخیره میشه. و Textbox بالایی برای اینه که بگید این الگو چه حرفی هست که توی این مطلب نیازی به پر کردن اون نیست چون ما بحثمون یادگیری Unsupervised هست. توی مطالب بعدی برای یادگیری Supervised به این فیلد نیاز خواهیم داشت.
خوب من برای اینکه مثال پیچیده نشه ۳ حرف رو می خوام به کامپیوتر یاد بدم. A و C و Z!
برای این کار برای هر کدوم از حروف چهار مثال وارد می کنم و دکمه ی Learn رو می زنم. توی شکل زیر می تونید هر ۱۲ الگو رو ببینید.

فایل خروجی مربوط به این الگوهای مثال از اینجا قابل دریافت هست.همونطور که می بینید هر ردیف به نظر من و شما عین هم هستند. اما اگر کمی بیشتر دقت کنیم می بینیم جای مربع های مشکی با هم فرق دارن. به نظر شما کامپیوتر هم خواهد فهمید هر ردیف نشاندهنده ی یک حرف مجزا هست؟
تشکیل شبکه ی عصبیخوب! حالا می خواهیم ساختار شبکه ی عصبی رو طراحی کنیم. برای این کار از JOONE Editor کمک می گیریم.
صفحه ی اول این نرم افزار به این شکل هست:

توی این مثال ما از یک لایه ی ورودی خطی ۶۴ نورونی استفاده می کنیم که هر نورون یک قسمت از ماتریسی که در بخش قبل گفتیم رو به عنوان ورودی می گیره. به عنوان خروجی هم از یک لایه ی ۳ نورونی WinnerTakeAll استفاده می کنیم. در این نوع خروجی یکی از نورون ها ۱ و بقیه ۰ خواهند بود که برای تقسیم بندی بسیار مناسب هست.

برای شروع ابتدا یک لایه ی FileInput ایجاد می کنیم. توسط این ابزار می تونیم یک فایل رو به عنوان ورودی به شبکه بدیم.
روی FileInput کلیک راست کرده و در Properties اون فایل درست شده در مرحله ی قبلی رو به عنوان fileName انتخاب می کنیم و به عنوان Advanced Column Selector مقدار ۱-۶۴ رو وارد می کنیم تا برنامه متوجه بشه باید از ستون های ۱ تا ۶۴ به عنوان ورودی استفاده کنه.

ایجاد یک لایه ی خطی:

مرحله ی بعدی ایجاد یک Linear Layer یا لایه ی خطی هست. بعد از ایجاد این لایه Properties اون باید به شکل زیر باشه:

همونطور که می بینید تعداد ردیف ها ۶۴ مقداردهی شده که دلیلش این هست که ۶۴ ورودی داریم.
حالا با انتخاب FileInput و کشیدن نقطه ی آبی رنگ سمت راست اون روی Linear Layer خروجی FileInput یعنی اطلاعات فایل رو به عنوان ورودی Linear Layer انتخاب می کنیم.
تا این لحظه ما یک لایه ی ۶۴ نورونه داریم که ورودی اون مقادیر مثال های تولید شده در مرحله ی قبل هست.

ایجاد لایه ی WinnerTakeAll :

خوب توی این مرحله لایه ی خروجی که یک لایه ی WinnerTakeAll هست رو تولید می کنیم. Properties این لایه باید به شکل زیر تغییر پیدا کنه تا اطمینان پیدا کنیم الگوها به سه دسته تقسیم میشن:

حالا باید بین لایه ی خطی و لایه ی WinnerTakeAll ارتباط برقرار کنیم. برای این کار باید از Kohonen Synapse استفاده کنیم و Full Synapse جواب نخواهد داد. پس روی دکمه ی Kohonen Synapse کلیک کرده و بین لایه ی خطی و لایه ی WinnerTakeAll ارتباط ایجاد می کنیم.
در آموزش های بعدی فرق انواع سیناپس ها رو بررسی خواهیم کرد.آموزش شبکه

تا این لحظه شبکه باید به این شکل باشه. حالا می تونیم آموزش شبکرو شروع کنیم. برای این کار در منوی Tools بخش Control Panel رو انتخاب می کنیم. و در صفحه ی جدید learningRating و epochs و training pattern و learning رو به شکل زیر تغییر می دیم.

epochs تعداد دفعاتی که مرحله ی آموزش تکرار میشرو تعیین می کنه.
learningRate ضریبی هست که در یادگیری از اون استفاده می شه. بزرگ بودن اون باعث میشه میزان تغییر وزن نورون ها در هر مرحله بیشتر بشه و سرعت رسیدن به حالت مطلوب رو زیاد می کنه اما اگر مقدار اون خیلی زیاد شه شبکه واگرا خواهد شد.
training patterns هم تعداد الگو هایی که برای آموزش استفاده می شن رو نشون می ده که در این مثال ۱۲ عدد بود.
بعد از اینکه تمام تغییرات رو ایجاد کردیم دکمه ی Run رو می زنیم و منتظر می شیم تا ۱۰۰۰۰ بار عملیات یادگیری انجام بشه.

تبریک می گم! شما الان به کامپیوتر سه حرف A و C و Z رو یاد دادید!
اما خوب حالا باید ببینید کامپیوتر واقعا یاد گرفته یا نه.
برای این کار از یک لایه ی FileOutput استفاده می کنیم تا خروجی شبکرو داخل یک فایل ذخیره کنیم.
Properties لایه ی FileOutput باید بصورت زیر باشه:

همونطور که می بینید به عنوان fileName مقدار c:\output.txt رو دادیم. یعنی خروجی شبکه در این فایل ذخیره میشه.
حالا کافیه لایه ی WinnerTakeAll رو به لایه ی FileOutput متصل کنیم.
بعد از متصل کردن این دو لایه شکل کلی باید بصورت زیر باشه:

برای اینکه فایل خروجی ساخته بشه باید یک بار این شبکرو اجرا کنیم. برای این کار مجددا در منوی Tools بخش Control Panel رو انتخاب می کنیم و در اون learning رو False و epochs رو ۱ می کنیم تا شبکه فقط یک بار اجرا شه. پس از تغییرات این صفحه باید به شکل زیر باشه:

حالا با توجه به اینکه من اول چهار مثال A رو وارد کردم و بعد به ترتیب چهار مثال C و چهار مثال Z رو ببینیم خروجی این شبکه به چه شکل شده.
باور کردنی نیست! خروجی به این شکل در اومده:

۱٫۰;۰٫۰;۰٫۰
۱٫۰;۰٫۰;۰٫۰
۱٫۰;۰٫۰;۰٫۰
۱٫۰;۰٫۰;۰٫۰
۰٫۰;۱٫۰;۰٫۰
۰٫۰;۱٫۰;۰٫۰
۰٫۰;۱٫۰;۰٫۰
۰٫۰;۱٫۰;۰٫۰
۰٫۰;۰٫۰;۱٫۰
۰٫۰;۰٫۰;۱٫۰
۰٫۰;۰٫۰;۱٫۰
۰٫۰;۰٫۰;۱٫۰

همونطور که می بینید ۴ خط اول که مربوط به A هستن ستون اولشون ۱ هست و در چهار خط دوم ستون دوم و در چهار خط سوم ستون سوم!
این یعنی کامپیوتر بدون اینکه کسی به اون بگه کدوم مثال ها کدوم حرف هست خودش فهمیده و اون ها رو دسته بندی کرده.
سوال :  ممکنه چون پشت هم دادید مثال هر حرف رو اینطوری نشده؟
جواب : نه! کامپیوتر که نمی دونسته من می خوام مثال های هر حرف رو پشت سر هم بدم! من برای راحتی خودم این کار رو کردم. شما می تونی ورودی هاتو غیر مرتب بدی!
سوال : دلیل خاصی داره که در A ستون اول ۱ هست و …
جواب : نه! ممکن بود برای A ستون دوم ۱ بشه و یا هر حالت دیگه. شما اگر امتحان کنید ممکنه تفاوت پیدا کنه. اما مهم اینه در تمام A ها یک ستون خاص مقدارش ۱ و بقیه ی ستون ها مقدارشون صفر می شه. پس یعنی کامپیوتر تونسته به خوبی تقسیم بندی کنه.

حالا می خوایم شبکرو با سه مثال جدید تست کنیم که در مثال های آموزشی نبوده! برای این کار من با استفاده از برنامه ی تولید الگو ۳ مثال جدید درست می کنم و به عنوان فایل ورودی در شبکه فایل جدید رو انتخاب می کنم.
توی شکل زیر سه مثال جدید رو می تونید ببینید:

برای جذابیت علاوه بر این سه مثال ۲ مثال دیگه هم که حروف خاصی نیستند گذاشتم!

فایل خروجی این مثال ها از اینجا قابل دریافت هست.

خوب حالا بگذارید ببینیم کامپیوتر چه جوابی می ده. با توجه به اینکه اول مثال C بعد مثال Z و بعد مثال A رو وارد کردم. دو مثال بعدی هم به ترتیب مثال بد خط سمت چپ و مثال بد خط سمت راست هستند. و اما جواب:

۰٫۰;۱٫۰;۰٫۰
۰٫۰;۰٫۰;۱٫۰
۱٫۰;۰٫۰;۰٫۰
۰٫۰;۰٫۰;۱٫۰
۰٫۰;۱٫۰;۰٫۰

کامپیوتر سه مورد اول رو به خوبی C و Z و A تشخیص داده. و دو مورد بد خط هم به ترتیب از چپ به راست Z و C تشخیص داده!
حتی برای انسان هم سخته فهمیدن اینکه مورد های چهارم و پنجم چی هستند اما اگر خوب دقت کنید می بینید به مواردی که کامپیوتر خروجی داده نزدیک تر هستند.
کامپیوتر شعور نداره! اما ما سعی کردیم طریقه ی عملکرد مغز رو به صورت خیلی ابتدایی و به ساده ترین نحو توش شبیه سازی کنیم! ”
تو  این مطلب دیدیم که کامپیوتر تونست بدون اینکه ما براش مثال هایی بزنیم و بگیم هر کدوم چه حرفی هستند و فقط با دادن تعداد دسته ها، مثال ها رو به سه دسته همونطوری که انسان ها تقسیم می کنند تقسیم کنه. همونطور که گفتیم به این نوع دسته بندی، دسته بندی Unsupervised میگن.
منبع

خوانش پلاک خودرو از تصاویر جاده‌ای

(پیاده سازی شده برای پلاک های ایرانی)

این الگوریتم (تشخیص پلاک خودرو) با نرم افزار MATLAB 2011 نوشته شده است برای خواندن پلاک که بدون نویز و خرابی هستند خوب جواب میدهد…البته دیتا بیس کاراکترها رو خودتون به راحتی میتوانید بیشتر کنید تا پاسخ دهی قویتر شود …فعلا فقط یک تصویر به عنوان آزمایش جهت تست برنامه قرار داده شده .

همچنین به علت ضیق وقت قسمت شناسای کاراکترها و تبدیل آنها به عدد و حروف فارسی رو قوی نکردم…شما میتونید این قسمت را برای جوابدهی بهتر دستکاری کنید… در ضمن اگر خواستین از نحوه فرمولبندی و کارکرد برنامه سر دربیارید حدود ۲۰ صفحه هم گزارش تهیه شده ، فایل پاور پوینتی که برای ارائه پروژه تشخیص پلاک خودرو آماده شده نیز آپلود گردیده است.

فقط قبل از اجرای برنامه این مراحل رو طی کنید:
۱- مسیر عکس خودرو(glx.jpg) رو وارد کنید
۲-دیتا بیس (فایل زیپ) رو دانلود کنید
۳-مسیر دیتا-بیس کاراکترها رو درست وارد کنید.
۴-برنامه رو اجرا کنید-نتایج رو صفحه کامند matlab نمایش داده میشود.
۵-هر جا خواستید از پشت دستور imshow و figure علامت % رو حذف کنید تا کارهای که روی تصویر انجام میشود رو مرحله به مرحله ببینید.
۶-برنامه را اجرا کنید و نتایج را در صفحه متلب ببیند.

 

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

تعداد صفحات پی دی اف : ۱۸

تعداد صفحات پاور پوینت : ۱۸

سورس کد : نرم افزار متلب Matlab

قیمت : رایگان

کلمه عبور فایل : behsanandish.com

 

دانلود

 

 

 

نکته : شرکت بهسان اندیش تولید کننده سامانه های هوشمند مفتخر به تولید یکی از دقیقترین و سریعترین سامانه های جامع کنترل تردد خودرو می باشد که می توانید جهت آشنایی با این محصول به لینک :سامانه جامع کنترل تردد خودرو بهسان(پلاک خوان) مراجعه فرمایید.

سورس برنامه در نرم افزار متلب:


clear all
close all
clc

p0=imread('E:\NIT\DIP\dip data proj\car\glx.jpg');
p=rgb2gray(p0);
p=im2double(p);

f=fspecial('gaussian');
pf=imfilter(p,f,'replicate');
%imshow(pf)
%figure
Pm=mean2(pf); %Average or mean of matrix elements
Pv=((std2(pf))^2); %the variance of an M-by-N matrix is the square of the standard deviation
T=Pm+Pv;

% taerife astane............................................
[m n]=size(pf);
for j=1:n
 for i=1:m
 if pf(i,j)>T;
 pf(i,j)=1;
 else
 pf(i,j)=0;
 end
 end
end

ps=edge(pf,'sobel');
%imshow(ps)
%figure
pd=imdilate(ps,strel('diamond',1));
pe=imerode(pd,strel('diamond',1));
pl=imfill(pe,'holes');
[m n]=size(pl);

%barchasb gozary..............................................
pll=bwlabel(pl);
stat =regionprops(pll,'Area','Extent','BoundingBox','Image','Orientation','Centroid');
index = (find([stat.Area] == max([stat.Area]))); %meghdare barchasb dakhele bozorgtarin masahat ra mikhanad
ppout=stat(index).Image;
%imshow(ppout);
%figure

% biron keshidane mokhtasate pelak.............................
x1 = floor(stat(index).BoundingBox(1)); %shomare stone awalin pixel (B = floor(A) rounds the elements of A to the nearest integers less than or equal to A)
x2 = ceil(stat(index).BoundingBox(3)); %pahnaye abject dar sathe ofoghi(B = ceil(A) rounds the elements of A to the nearest integers greater than or equal to A)
y1 = ceil(stat(index).BoundingBox(2)); %shomare satre avalin pixel(B = ceil(A) rounds the elements of A to the nearest integers greater than or equal to A)
y2 = ceil(stat(index).BoundingBox(4)); %pahnaye abject dar sathe amodi(B = ceil(A) rounds the elements of A to the nearest integers greater than or equal to A)
bx=[y1 x1 y2 x2];
ppc=imcrop(p0(:,:,:),[x1,y1,x2,y2]);
%imshow(ppc)
%figure
ppg=imcrop(p(:,:),[x1,y1,x2,y2]);
%imshow(ppg)
%figure

%plate enhancment..............................................
ppcg=rgb2gray(ppc);
ppcg=imadjust(ppcg, stretchlim(ppcg), [0 1]); % specify lower and upper limits that can be used for contrast stretching image(J = imadjust(I,[low_in; high_in],[low_out; high_out]))
ppg=im2double(ppcg);
pb=im2bw(ppg);%im2bw(I, level) converts the grayscale image I to a binary image
%imshow(pb)
%figure

%rotate correction..............................................
if abs(stat(index).Orientation) >=1; %The orientation is the angle between the horizontal line and the major axis of ellipse=angle
 ppouto=imrotate(ppout,-stat(index).Orientation); %B = imrotate(A,angle) rotates image A by angle degrees in a counterclockwise direction around its center point. To rotate the image clockwise, specify a negative value for angle.
 pbo=imrotate(pb,-stat(index).Orientation);
 angle = stat(index).Orientation;
else
 pbo=pb;
end;
%imshow(pbo)

pbod=imdilate(pbo,strel('line',1,0));
pbodl=imfill(pbod,'holes');
px = xor(pbodl , pbod);

pz= imresize(px, [44 250]); % 4*(57*11)=(chahar barabar size plake khodroye irani)

%barchasb zanye plak..........................................
stat1 = regionprops(bwlabel(pz,4),'Area','Image');
index1 = (find([stat1.Area] == max([stat1.Area])));
maxarea =[stat1(index1).Area];%braye hazfe neweshteye iran va khatahaye ehtemali
pzc=bwareaopen(pz,maxarea-200); %maxarea(1,1) meghdare structur ra adres dehi mikonad,va migoyad object haye ka mte z an ra hazf konad
%histogram plak......
%v=sum(pzc);
%plot(v);

%biron keshidan karakterha......................................
stat2=regionprops(pzc,'Area','BoundingBox','Image','Orientation','Centroid');
cx=cell(1,8);
for i=1:8
 x=stat2(i).Image;
 rx=imresize(x, [60 30]);
 %imshow(rx)
 %figure
 cx{1,i}=rx;
 %fx=mat2gray(cx{1,1});
 %imshow(cx{1,2})
 
 imwrite(rx,['E:\NIT\DIP\dip data proj\char\car\glx\' num2str(i) '.jpg']);
end

%khandane karakterha.........mini database1...................

for i=1:1
 for j=1:8
 temp=imread(['E:\NIT\DIP\dip data proj\char\car\glx\' num2str(j) '.jpg']);
 temp=im2bw(temp);
 nf1=temp.*cx{1,i};
 nf2=sum(sum(nf1));
 nf(j)=nf2/(sum(sum(temp)));
 mx=max(nf(j));
 
 
 if nf(1,1)== mx
 disp(1);
 else
 if nf(1,2)== mx
 disp(5);
 else
 if nf(1,3)== mx
 disp('j');
 else
 if nf(1,4)== mx
 disp(6);
 else
 if nf(1,5)== mx
 disp(3);
 else
 if nf(1,6)== mx
 disp(1);
 else
 if nf(1,7)== mx
 disp(7);
 else
 if nf(1,8)== mx
 disp(2);
 
 
 end
 end
 end
 end
 end
 end
 
 end
 
 end
 
 
 end
 
end