MikeWhite 0 Жалоба Опубликовано October 8, 2015 Здравствуйте! на просторах интернета набрел на ваш форум и прошу у вас помощи.Пишу проект для обработки отпечатков пальцев на платформе Android, OpenCV подключил, информацию по обработке впитал но на практике что то ничего не получается:Для начала как я понимаю мне необходимо построить карту направлений и в последствии построить Габор изображение которое сгладит все неровности и после его бинаризации строится скелет в котором находим конечные точки и развлетвления.конкретно после всех преобразований должно получиться подобное изображение:для нахождения карты направлений я использовал алгоритм: Smorodov с сайта stackoverflowконкретно моя реализация: Imgproc.cvtColor(mRgba, src_f, Imgproc.COLOR_BGR2GRAY); //src_f.convertTo(src_f, CvType.CV_8UC1); normalize(src_f, src_f, 0, 255, Core.NORM_MINMAX, CvType.CV_8UC1); threshold(src_f, src_f, 128, 255, Imgproc.THRESH_BINARY); // orientation if(orientCalc) { int scale = 2; int delta = 0; Imgproc.Sobel(src_f, mHist, CvType.CV_32F, 1, 0, 7, scale, delta); Imgproc.Sobel(src_f, mGray, CvType.CV_32F, 0, 1, 7, scale, delta); int aprox_size=10; aproxorientation=new Mat(mHist.rows()/aprox_size,mHist.cols()/aprox_size,CvType.CV_32F,new Scalar(0, 0, 0)); orientation = new Mat(mHist.rows(), mHist.cols(), CvType.CV_32F); //to store the gradients magnit=new Mat(mHist.rows(), mHist.cols(), CvType.CV_32F); phase(mHist, mGray, orientation, false); magnitude(mHist, mGray, magnit); normalize(magnit, magnit, 0, 1, Core.NORM_MINMAX); showBitmap(R.id.imageViewX, mHist); showBitmap(R.id.imageViewY, mGray); orientCalc=false; float results; merge(Arrays.asList(src_f, src_f, src_f), img); logMInfo(orientation); for (int l=0;l<= mHist.rows()-aprox_size;l+= aprox_size) { for (int k=0;k<= mHist.cols()-aprox_size;k+= aprox_size) { results = GetAngle(l,k,aprox_size); Point p1,p2; p1=new Point((k + aprox_size/2), (l + aprox_size/2)); p2=new Point((k + aprox_size/2), (l + aprox_size/2)); p1.x=p1.x-(aprox_size/2)*Math.cos(results); p1.y=p1.y-(aprox_size/2)*Math.sin(results); p2.x=p2.x+(aprox_size/2)*Math.cos(results); p2.y=p2.y+(aprox_size/2)*Math.sin(results); Imgproc.line(img,p1,p2,new Scalar(255,0,0),1); } } } showBitmap(R.id.imageViewO, orientation);код апроксимации с кешем:float GetAngle(int x,int y,int d){ float res=0; if(orientCalc==false){ res=(float)aproxorientation.get(x/d,y/d)[0]; if(res==0){ res=GetWeightedAngle(new Mat(magnit,new Rect(y, x, d, d)),new Mat(orientation,new Rect(y, x, d, d))); aproxorientation.put(x/d,y/d,res); } } return res; } float GetWeightedAngle(Mat mag,Mat ang) { float res=0; float n=0; double a=0; for (int i=0;i< mag.rows();++i) { for (int j=0;j< mag.cols();++j) { ang.put(i,j,ang.get(i,j)[0]*mag.get(i,j)[0]); res+=(float)ang.get(i,j)[0]; n+=mag.get(i,j)[0]; } } if(n==0)return 0; res/=n; return res; }после этого я получил изображения:где видно что на участках близких к 2pi появляются артефакты и направления расчитываются неверно, как это побороть я не знаю.но даже с такой картой ориентации я постарался постороить габор фильтр:if(((CheckBox)findViewById(R.id.checkBox)).isChecked()) { int kernel_size = 3; double sig = 0.5, th = 0, lm = 0.85, gm = 1, ps = 274; sig = ((SeekBar) findViewById(R.id.seekBarSig)).getProgress() / 100.0; lm = ((SeekBar) findViewById(R.id.seekBarLambda)).getProgress() / 1000.0; int grid_size = 10; Log.i("Finger", "getGaborKernel(" + sig + "," + th + "," + lm + ")"); Log.i("Finger", "src_f.type() " + CvType.typeToString(src_f.type()) + " size() " + src_f.cols() + "x" + src_f.rows()); int x1, x2; src_f.convertTo(src_f, CvType.CV_32F); Imgproc.blur(src_f, src_f, new Size(3, 3)); Mat kernel; for (int l=0;l<= src_f.rows()-grid_size;l+= grid_size) { for (int k=0;k<= src_f.cols()-grid_size;k+= grid_size) { Mat roi3 = new Mat(src_f, new Rect(k, l, grid_size, grid_size)); double ang = GetAngle(l,k,grid_size); kernel = Imgproc.getGaborKernel(new Size(kernel_size, kernel_size), sig, ang, lm, gm); Imgproc.filter2D(roi3, roi3, CvType.CV_32F, kernel); } } src_f.copyTo(tmp); }получилось вообще непонятно что: Посему прошу у вас помощи в редактировании кода либо если завалялось что готовое, это мой первый проект на opencv и посему не сильно ругайтесь я уже третий месяц пытаюсь во всем этом разобраться и в теории все понятно а практических реализаций я не нашел.Заранее Огромное Спасибо! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 8, 2015 По поводу углов, заверните их в интервал 0-180, это должно решить проблему.По поводу клеток, сделайте свертку полного изображения 8-12 фильтрами с разными ориентациями, и для каждого угла берите точку из своего изображения. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
MikeWhite 0 Жалоба Опубликовано October 9, 2015 заворачивал в 0-180 не помогает:причитна в появлении артифактов в себелевском смещении (с лева 2 картинки по X и Y) на них явно видно искажения Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 10, 2015 Посмотрите проект на питоне, думаю он делает как раз то что Вам нужно:https://github.com/rtshadow/biometrics Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
MikeWhite 0 Жалоба Опубликовано October 23, 2015 Огромное спасибо за пример, по нему я собрал расчет углов (хотя очень медленно).А вот дальше я опять застрял пытаясь понять как строится gabor изображение? требуется по мимо углов еще доп параметры смещений, как их рассчитать? После запуска примера его описанные функции работают а вот именно преобразование из исходного в enhanced не работает.Есть ли подобный пример но с использование OpenCV (C++,Java)? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 31, 2015 Ну, примеров на CPP нет, но могу теории подкинуть https://drive.google.com/file/d/0Bxk3hR536PxSWHJ4V2dZanJHbms/view?usp=sharing Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах