site logo
  • Կայքի մասին
  • Ծրագրավորում
  • Ժեշտ
  • Անվտանգություն
  • Հարց ու Պատասխան (ՀուՊ)
Մայիս 21, 2013  |  By Neutrino In

OpenCv մեքենայական տեսողության գրադարանի տեղակայում և ֆիքսված դիրքով պետավտոհամարանիշների սեգմենտացում՝ առանձին թվանշանների առանձնացում։ Մաս 1։

Screenshot from 2013-05-21 19:35:52

OpenCV -ն Բաց կոդով մեքենայական տեսողության գրադարան է, որը պարունակում է մեքենայական տեսողության, պատկերների մշակման և թվային մեթոդների ավելի քան 500 ֆունկցիաներ։ Գրադարանը գրված է C/C++ լեզվով և ակտիվ մշակման փուլում է գտնվում python, java, ruby, Matlab, Lua լեզուների համար տարբերակները։ Գրադարանը կարող է ազատորեն կիրառվել ակադեմիական և կոմերցիոն նպատակների համար և տարածվում է BSD լիցենզիայի պայմաններով։ Ներկայումս հասանելի են Windows, Linux և Mac օպերացիոն համակարգերի համար նախատեսված տարբերակները։ Գրադարանը կարող էք բեռնել արտադրողի կայքից: Բեռնեք գրադարանի վերջին տարբերակը՝ համապատասխան օպերացիոն համակարգի համար, որի վրա աշխատելու էք։ Opencv գրադարանը լրացուցիչ արագացում է ստանում intel միկրոպրոցեսորներով պլատֆորմների վրա շնորհիվ intel® Image Processing Library (IPL ազդանշանների, պատկերների, մեդիա կոդեկների մշակման ցածր մակարդակի գրադարան) գրադարանի։ Opencv -ն ավտոմատ կարողանում է հայտնաբերել IPL գրադարանի առկայությունը։ IPL -ը վճարովի է։

OpenCv գրադարանը բաղկացած է հետևյալ բաղկացուցիչ մասերից CXCORE, CV, ML, HIGHGUI, CVCAM, CVAUX մոդուլներից։

CXCORE – միջուկը բաղկացած է

– բազային հանգույցներ,

– մատրիցների հանրահաշիվ,

– հիշողության հետ աշխատանքի ալգորիթմներ,

– տիպերի ձևափոխության ալգորիթմներ,

– սխալների մշակման ալգորիթմներ,

– XML ֆայլերում գրել/կարդալու ալգորիթմներ,

– 2D գրաֆիկների հետ աշխատելու ալգորիթմներ։

 CV – պատկերների մշակման, մեքենայական տեսողության մոդուլը պարունակում է․

– պատկերների հետ աշխատանքի ֆունկցիաներ․  ձևափոխություններ, զտումներ և այլն,

– պատկերների վերլուծության ֆունկցիաներ․ կոնտուրների փնտրում, հիստոգրամներ և այլն,

– շարժումների վերլուծության ալգորիթմներ, օբյեկտների տեղաշարժումների հետևում,

– օբյեկտների ճանաչման ալգորիթմներ․ մարդկանց դեմքերի, առարկաների և այլն,

– տեսախցիկների ստուգաճշտման ալգորիթմներ։

ML– սա չեմ կարող թարգմանել Machine Learning (մեքենայական կրթություն կամ մեքենայական սովորում չի լինում էլի 😉 ):

HIGHGUI –  օգտագործողի ինտերֆեյսի ստեղծման մոդուլը բաղկացած է՝

– պատուհանների ստեղծում,

– պատկերների արտածում,

– վիդոեպատկերների զավթում (video capture) տեսախցիկներից և ֆայլերից,

– պատկերների կարդալ/գրել։

CVCAM – թվային տեսախցիկներից վիդեոպատկերների զավթում (video capture)։

CVAUX – ֆուկնցիաներ են, որոնք նախատեսված են․

– տարածական տեսողության,

– դիմագծերի փնտրման և նկարագրման,

– ստերեո համապատասխանությունների փնտրման,

– հյուսվածքների (texture) նկարագրություն:

OpenCv գրադարանը կարող է աշխատել հետևյալ կոմպիլյատորների հետ․

– Windows – Microsoft Visual C++, Borland C++, Intel Compiler, MinGW,

– Linux – GCC, Intel Compiler,

– Mac – Intel Compiler, Carbon և այլ։

Վերջացնելով OpenCv գրադարանի համառոտ նկարագրությունը՝ անցնենք նրա տեղակայմանը Linux օպերացիոն համակարգում։

Դրա համար հաջորդաբար կատարում ենք ստորև բերված հրամանները․

1. Թարմացնում ենք օպերացիոն համակարգում եղած ծրագրային փաթեթները և ծրագրերը․

1.1 sudo apt-get update

1.2 sudo apt-get upgrade

2. Հետևյալ հրամանով տեղակայում ենք հետևյալ ծրագրերը․

sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff4-dev libjasper-dev libopenexr-dev cmake 
python-dev python-numpy python-tk libtbb-dev libeigen2-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev 
libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common 
texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev

3. Նյութի սկզբում բերված հղումով քաշում և ապարխիվացնում ենք OpenCV գրադարանը, իմ մոտ 2.4.0 տարբերակն է, դուք կարող էք կրկնել նույնը՝ փոխելով միայն OpenCV-2.4.0 ձեր տարբերակի անունով․

tar -xvf OpenCV-2.4.0.tar.bz2
cd OpenCV-2.4.0/
mkdir build
cd build

4. Կոնֆիգուրացնում և նախնական կարգաբերումներ ենք տալիս տեղակայումից առաջ․

cmake -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON
-D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON
-D WITH_OPENGL=ON ..

5. Կոմպիլացնում ենք գրադարանի կոդը

make

6. Տեղակայում ենք գրադարանը

sudo make install

7. Որպեսզի մեր ծրագիրը կատարման ժամանակ հղվի OpenCV գրադարանի վրա պետք է կոնֆիգուրացնել /etc/ld.so.conf ֆայլը․

sudo vim /etc/ld.so.conf.d/opencv.conf

Եվ բացված ֆայլում ավելացնում ենք հետևյալ տողը․

/usr/local/lib

Եթե vim տեքստային խմբագրիչը չկա ձեր համակարգչում կարող էք դրա փոխարեն օգտագործել ցանկացած ուրիշը՝ օրինակ gedit -ը։

7. Տերմինալի մեջ գրում ենք

sudo ldconfig

8. Բացում ենք bash.bashrc ֆայլը

sudo gedit /etc/bash.bashrc

և որևէ ազատ տողում ավելացնում ենք

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH

Վերջ գրադարանը տեղակայված է։

Այժմ խնդիր է դրված առանձնացնել ֆիքսված դիրքով տեղակայված պետավտոհամարանիշի առանձին թվանշանները․

Բերենք կոդը՝ գրված C++ լեզվով․

DetectNumbers.h

#ifndef DETECTNUMBERS_H
#define DETECTNUMBERS_H

#include <baseapi.h>
#include "opencv/cv.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <opencv2/opencv.hpp>
#include <string>

namespace cvTech
{
	class cvDetection;
}

class cvTech::cvDetection
{
	private:
		std::string mPath;
		int mThreshold;
		int mMaxValue;
		cv::Mat mImage;

	public:
 		virtual void cvShowImage(const IplImage& im);
		virtual void cvArrToMatrix(const IplImage& src, cv::Mat& m);
    	virtual cv::Mat cvConverteToSmooth(cv::Mat s, size_t w, size_t h);
 		virtual IplImage* cvCreateNewImage(const IplImage* src, int depth, int a);
		virtual IplImage* cvCopySourceImage(IplImage* src);
		virtual IplImage* cvTransformImageEx(IplImage* gray, IplImage* binary, size_t radius);
		virtual IplImage* cvCvtColors();
		virtual IplImage* cvBinarizeImage(const IplImage* src, IplImage* gray);
		virtual IplImage* cvTrnasformToCanny(IplImage* morf, IplImage* gray, int a, int b, int c);
		virtual CvSeq* cvFindContoursInToImage(IplImage* binary);
		virtual void show();

	public:
		cvDetection(const std::string& str, int threshold, int maxvalue);
		cvDetection(const cvDetection& d);
		cvDetection& operator=(const cvDetection& d);
		std::string cvGetImagePath() const;
		cv::Mat cvGetImage() const;
		void cvSetImagePath(const std::string& str);
		int cvGetThreshold() const;
		int cvGetMaxValue() const;
};

#endif // DETECTNUMBERS_H

DetectNumbers.cpp

#include "DetectNumbers.h"

#include <cassert>

const char* wndname = "Detect Car Numbers";

cvTech::cvDetection::cvDetection(const std::string& str, int threshold, int maxvalue) :
	  mPath(str)
	, mThreshold(threshold)
	, mMaxValue(maxvalue)
{
	mImage = cv::imread(mPath, 1);
}

void cvTech::cvDetection::cvSetImagePath(const std::string& str)
{
	assert(!str.empty());
	mPath = str;
}

std::string cvTech::cvDetection::cvGetImagePath() const
{
	return mPath;
}

cv::Mat cvTech::cvDetection::cvGetImage() const
{
	return mImage;
}

int cvTech::cvDetection::cvGetThreshold() const
{
	return mThreshold;		
}

int cvTech::cvDetection::cvGetMaxValue() const
{
	return mMaxValue;
}

cvTech::cvDetection::cvDetection(const cvDetection& d)
{
	this->mPath = d.cvGetImagePath();
        this->mImage = d.cvGetImage();
	this->mThreshold = d.cvGetThreshold();
	this->mMaxValue = d.cvGetMaxValue();
}

cvTech::cvDetection& cvTech::cvDetection::operator=(const cvDetection& d)
{
	if(&d == this)
	{
		return (*this);
	}
	this->mPath = d.cvGetImagePath();
        this->mImage = d.cvGetImage();
	this->mThreshold = d.cvGetThreshold();
	this->mMaxValue = d.cvGetMaxValue();
	return (*this);
}

void cvTech::cvDetection::cvShowImage(const IplImage& im)
{
	cv::Mat temp;
    cvArrToMatrix(im, temp);
	imshow(wndname, temp);
	int c = cv::waitKey();
}

void cvTech::cvDetection::cvArrToMatrix(const IplImage& src, cv::Mat& m)
{
	m = cv::cvarrToMat(&src);
}

cv::Mat cvTech::cvDetection::cvConverteToSmooth(cv::Mat src, size_t w, size_t h)
{
	IplImage i = mImage;
	IplImage* img = cvCloneImage(&i);
	IplImage s = src;
	cvSmooth(&s, img, CV_GAUSSIAN, w, h);
	cv::Mat m(img);
	return m;
}

IplImage* cvTech::cvDetection::cvCreateNewImage(const IplImage* src, int depth, int a)
{
	IplImage* dst = cvCreateImage(cvSize(src->width, src->height), depth, 1);
	assert(dst != 0);
	return dst;
}

IplImage* cvTech::cvDetection::cvCopySourceImage(IplImage* src)
{
	IplImage* dst = cvCloneImage(src);
	assert(dst != 0);
	return dst;
}

IplImage* cvTech::cvDetection::cvTransformImageEx(IplImage* gray, IplImage* binary, size_t radius)
{
	assert(binary != 0);
	IplConvKernel* kern = cvCreateStructuringElementEx(radius*2, radius*2, radius, radius, CV_SHAPE_RECT);
	IplImage img = mImage;
	IplImage* temp = cvCreateImage(cvSize(img.width, img.height), img.depth, 1);
	IplImage* dst = cvCopySourceImage(gray);
	cvMorphologyEx(binary, dst, temp, kern, CV_MOP_TOPHAT,1);
	assert(dst != 0);
	return dst;
}

IplImage* cvTech::cvDetection::cvCvtColors()
{
	IplImage img = mImage;
	IplImage* gray = cvCreateImage(cvSize(img.width, img.height), 8, 1);
	IplImage* img1 = cvCopySourceImage(&img);
	cvCvtColor(img1, gray, CV_RGB2GRAY);
	assert(gray!=0);
	return gray;
}

IplImage* cvTech::cvDetection::cvBinarizeImage(const IplImage* src, IplImage* gray)
{
	IplImage img = mImage;
	IplImage* binary = cvCreateNewImage(src, img.depth, 1);
	cvThreshold(gray, binary, mThreshold, mMaxValue, CV_THRESH_BINARY);
	assert(binary != 0);
	return binary;
}

IplImage* cvTech::cvDetection::cvTrnasformToCanny(IplImage* morf, IplImage* gray, int a, int b, int c)
{
	IplImage* canny = cvCopySourceImage(gray);
	assert(morf != 0);
	assert(canny != 0);
	cvCanny(morf, canny, a, b, c);
	assert(canny != 0);
	return canny;
}

CvSeq* cvTech::cvDetection::cvFindContoursInToImage(IplImage* binary)
{
	CvSeq *ptr,*polygon;
	CvMemStorage *mem;
	mem = cvCreateMemStorage(0);
	CvSeq *contours = 0;
	IplImage img = mImage;
	cvFindContours(binary, mem, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
	for (ptr = contours; ptr != NULL; ptr = ptr->h_next) 
	{
		double reg = fabs(cvContourArea(ptr, CV_WHOLE_SEQ));
	//		if(reg >10 && reg <600)
		{
			cvApproxPoly(ptr, sizeof(CvContour), mem, CV_POLY_APPROX_DP, 3, 1);
			CvScalar ext_color = CV_RGB( 255, 255, 255 ); 
			CvRect rectEst = cvBoundingRect( ptr, 0 );
			CvPoint pt1,pt2;
			pt1.x = rectEst.x;
			pt1.y = rectEst.y;
			pt2.x = rectEst.x+ rectEst.width;
			pt2.y = rectEst.y+ rectEst.height;
			int thickness =1 ;
			cvRectangle(&img, pt1, pt2, CV_RGB(80, 255, 0 ), thickness );
			cvResetImageROI(&img);
		}
	}
	assert(contours != 0);
	return contours;
}

void cvTech::cvDetection::show()
{
	imshow(wndname, mImage);
	int c = cv::waitKey();
}

main.cpp

#include "DetectNumbers.h"

#include <string>

int main()
{
	namespace T = cvTech; 
	std::string path("/home/vardan/detect/index.png");
	T::cvDetection* d = new T::cvDetection(path, 100, 200 );
	assert(d != 0);
	cv::Mat dst;
	cv::Mat img = d->cvGetImage();
	IplImage cp = img; 
	IplImage* sm = d->cvCopySourceImage(&cp);
	assert(sm != 0);
	cv::Mat m(sm);
	d->cvConverteToSmooth(m, 3, 3);
	IplImage* gray = d->cvCvtColors();
	IplImage* binary = d->cvBinarizeImage(&cp, gray);
//	IplImage* tr = d->cvTransformImageEx(gray, binary, 10);
//	assert(tr != 0);
//	IplImage* canny = d->cvTrnasformToCanny(tr, gray, 100, 500, 3);
//	assert(canny != 0);
	d->cvFindContoursInToImage(binary);
	d->show();
    if(d != 0)
	{
		delete d;
	}

	return 0;
}

Makefile

 

EXE=DetectNumbers

$(EXE) : $(EXE).cpp main.cpp $(EXE).h
	g++ -o $@ $^ `pkg-config opencv --cflags --libs tesseract` -ggdb

.PHONY : clean
clean:
	rm -rf $(EXE) $(EXE).o *.swf

Վերջապես ամեն ինչ արդեն պատրաստ է կարող ենք կոմպիլացնել կոդը և աշխատացնել (պետք է փոխեք պատկերի ճանապարհը ՝  /home/vardan/detect/index.png փոխարեն տալով ձեր պատկերի ճանապարհը): ՈՒնենք հետևյալ ֆայլերը DetectNumbers.h, DetectNumbers.cpp, main.cpp, makefile և դրանք գտնվում են օրինակ /home/ubuntu/opencv/my_cods/detect_car_numbers պանակում։ Կատարում ենք հետևյալ քայլերը․
1.

make

2.

./DetectNumbers

Արդյունքում կբացվի հետևյալ պատուհանը․

Screenshot from 2013-05-21 19:19:14
Տեսնում ենք, որ մեր ծրագիրը հաջող կարողացել է սեգմենտացնել պետհամարանիշի առանձին թվանշանները, բայց արդյունքը իդեալականին մոտ չէ, քանի որ առկա են բազմաթիվ մակաբուծային՝ ավելորդ կոնտուրներ։
Այդ արդյունքի համար մեղավոր է DetectNumbers.cpp ֆայլի 151 -րդ տողի փակված if(…) պայմանական անցման օպերատորը։ if(…) -ի ներսում էլ հենց ստուգվում է կոնտուրի չափերը և էկրանին պատկերվում են միայն անհրաժեշտ պայմաններին բավարարող կոնտուրները, տվյալ դեպքում if(reg >10 && reg <600) – ում ստուգվում է, եթե կոնտուրի մակերեսը մեծ է 10 -ից և փոքր է 600 -ից ապա դա համավում է թույլատրելի կոնտուր և պատկերվում է էկրանին։ Հիմա բացում ենք 151-րդ տողի այդ if(…) -ը և տեսնում․

Screenshot from 2013-05-21 19:35:52
Այս անգամ մեզ հաջողվեց բավական լավ արդյունք ստանալ։

Ինչպես համոզվեցիք ինքներդ՝ տարբեր համարանիշների դեպքում սեգմենտացման կայուն արդյունքներ ստանալու համար պետք է սստուգաճշտել կոնտուրների մակերեսը, չափսերը և այլ պարամետրեր։ Բացի այդ արդյունքների ճշտության աստիճանը կախված է նաև մուտքային պատկերի հստակության աստիճանից, մակաբուծային ստվերերի առկայությունից, համարանիշի դիրքից, անկյունից և այլն։ Ծրագրային կոդի բերված տարբերակը նախնական, սաղմնային տարբերակն է և չի կարող տալ արտադրական պահանջներին բավարարող կայուն արդյունքներ, բայց շատ և շատ դեպքերում այն թույլ է տալիս ստանալ բավականին լավ արդյունքներ։ Այս կոդը կարելի է կատարելագործել և ստանալ ավելի ստաբիլ արդյունքներ տվող ծրագիր։ Երկրորդ մասում կխոսենք OpenCV գրադարանի՝ բերված կոդում օգտագործված ֆունկցիաներից, սեգմենտացման ընդհանուր խնդիրներից և մեր ծրագրի կառուցվածքից։ Պրոյեկտի բոլոր ֆայլերը կարող էք բեռնել github.com -ի այս ռեպոզիտորիայից։

OpenCv մեքենայական տեսողության գրադարանի տեղակայում և ֆիքսված դիրքով պետավտոհամարանիշների սեգմենտացում՝ առանձին թվանշանների առանձնացում։ Մաս 1։, 10.0 out of 10 based on 18 ratings
*Nix-եր C և C++ C++ image segmentation OpenCV Ալգորիթմներ Լինուքս/Յունիքս հրամաններ Ծրագրավորում Կոմպիլյատորներ պատկերների ճանաչում
Previous StoryՀնարք odnoklassniki.ru-ում Модератор Одноклассников-ում
Next StoryHacker Typer զգացեք ձեզ ինչպես հաքեր Ճ

Comments: no replies

Join in: leave your comment Cancel Reply

(will not be shared)

Որոնում

Նշագրեր

*Nix-եր (18) android (17) C++ (19) C և C++ (27) Excel (10) html (10) Network Administration (16) System Administration (28) Windows 7 (14) Ալգորիթմներ (15) Անվտանգություն (29) ԳՆՈՒ/Լինուքս (16) Թեյնիկներին (57) Ժեշտ (44) Լակոնիկ (21) Լինուքս/Յունիքս հրամաններ (29) Լուսանկարչություն և մշակում (15) Խելախոսներ (19) Ծրագրավորման լեզուներ (16) Ծրագրավորում (64) Ծրագրեր (48) Հայականացում (28) Հումոր (11) Ուսումնական նյութեր (34) Սոցցանցային Հմտություններ (19) Վեբ (25) Վերլուծություն (10) Վորդպրես (21) ՏՏ և փիլիսոփայություն (21) Տվյալների բազաներ (12) Օպերացիոն համակարգեր (27) Օֆիսային ծրագրեր (22) անդրոիդ (16) բաշ (10) ինտերնետ (11) խելախոսներ (13) համացանց (15) հայատառ (10) հայերեն (11) հայերեն ստեղնաշար (11) հայկական սոֆթ (11) ստեղնաշար (10) սքրիփթ (14) վինդոուս (12) տեսանյութ (23)
Copyright ©2017 ThemeFuse. All Rights Reserved