nagoHok
Пользователи-
Количество публикаций
54 -
Зарегистрирован
-
Посещение
-
Days Won
1
nagoHok last won the day on August 12 2011
nagoHok had the most liked content!
Репутация
4 НовичекО nagoHok
-
Звание
Эксперт
-
Не советую использовать для этого таймер, ибо в карте сообщений системы он стоит самый последний, лучше для этого организовать отдельный поток.
-
я этими пользуюсь 1.rar
-
Оч сырой код, но более 50% локализует, предлагаю довести его до ума) #include "stdafx.h" #include "ContrastMap.h" #pragma warning (disable:4996) #include <cv.h> #include <opencv2\highgui\highgui_c.h> #include <math.h> #pragma comment(lib,"opencv_core220d.lib") #pragma comment(lib,"opencv_highgui220d.lib") #pragma comment(lib,"opencv_imgproc220d.lib") #pragma comment(lib,"opencv_video220d.lib") #pragma comment(lib,"opencv_legacy220d.lib") #ifdef _DEBUG #define new DEBUG_NEW #endif // The one and only application object CWinApp theApp; using namespace std; class CBlock { public: int m_nStartPoin; int m_nEndPoint; int m_nBlockLen; CBlock(void) { m_nStartPoin = 0; m_nEndPoint = 0; m_nBlockLen = 0; } virtual ~CBlock(void) { } void Empty() { m_nStartPoin = 0; m_nEndPoint = 0; m_nBlockLen = 0; } bool IsNull(){return m_nBlockLen ? false : true;} }; void SummRow(const IplImage* pSrc, CArray<double>& arRow) { arRow.RemoveAll(); arRow.SetSize(pSrc->height); for (int nPosY = 0; nPosY < pSrc->height; nPosY++) { int nOffset = pSrc->widthStep * nPosY; for (int nPosX = 0; nPosX < pSrc->widthStep; nPosX++) { arRow[nPosY] += (uchar)pSrc->imageData[nOffset + nPosX]; } } } void DrawGraf(IplImage* pSrc, const CArray<double>& arRow) { CvPoint ptLastPoint = cvPoint(0, 0); for (int nPos = 0; nPos < arRow.GetCount(); nPos++) { cvDrawLine(pSrc, ptLastPoint, cvPoint((int)arRow[nPos] / 200, nPos) , cvScalar(0), 1); ptLastPoint = cvPoint((int)arRow[nPos] / 200, nPos); } } void AplyFilter(const IplImage* pSrc, IplImage* pDest) { double arMask[9] = {0,0,0,0,0.5,0,0,0,0}; //double arSharp[9] = {0.1111, -0.8889, 0.1111, -0.8889, 4.1111, -0.8889, 0.1111, -0.8889, 0.1111}; CvMat matMask = cvMat(3, 3, CV_64FC1, arMask); cvFilter2D(pSrc, pDest, &matMask, cvPoint(-1,-1)); } void AplySobel(const IplImage* pScr, IplImage* pDest) { IplImage* pDst = cvCreateImage( cvSize(pScr->width, pScr->height), IPL_DEPTH_16S, pScr->nChannels); // применяем оператор Собеля cvSobel(pScr, pDst, 1, 0, 3); // преобразуем изображение к 8-битному cvConvertScale(pDst, pDest); cvReleaseImage(&pDst); } inline double GSmooth(double nDist, double nParam, double nParam2) { return exp((-(nDist * nDist)/nParam)) / nParam2; } void GauseSmooth(const CArray<double>& arSrc, CArray<double>& arDest) { arDest.RemoveAll(); double nParam = 3.; int nAperture = 5; double nParam1 = 2* (nParam * nParam); double nParam2 = sqrt(2 * CV_PI) * nParam; arDest.SetSize(arSrc.GetCount()); for (int nPos = 0; nPos < arSrc.GetCount() - 1; nPos++) { double s = 0.; for (int nK = max(nPos - nAperture, 0); nK < min(arSrc.GetCount() - 1, nPos + nAperture); nK++) { s += arSrc[nK] * GSmooth(abs(nPos - nK), nParam1, nParam2); } arDest.SetAt(nPos, s); } } void Func(IplImage* pImg, int nPosY, CArray<double>& arFunc) { arFunc.RemoveAll(); double _f = 0.; int nLinePos = nPosY * pImg->widthStep; arFunc.SetSize( pImg->widthStep - 1); for(int nPos = 0; nPos < pImg->widthStep - 1; nPos++) { _f += abs(pImg->imageData[nLinePos + nPos + 1] - pImg->imageData[nLinePos + nPos]); arFunc.SetAt(nPos, _f); } } void GetFirstDiff(const CArray<double>& arSrc, CArray<double>& arDest) { CArray<double> arTmp; arTmp.SetSize(arSrc.GetCount()); for (int nPos = 1; nPos < arSrc.GetCount(); nPos++) { if(nPos + 1 > arSrc.GetCount() - 1) continue; double ndY = arSrc[nPos + 1] - arSrc[nPos]; arTmp.SetAt(nPos, ndY); } arDest.RemoveAll(); arDest.Copy(arTmp); arTmp.RemoveAll(); } int GetMaxPosition(CArray<double>& arGraf) { int nMax = 0; for (int nPos = 0; nPos < arGraf.GetCount(); nPos++) { if(arGraf[nPos] > arGraf[nMax]) nMax = nPos; } return nMax; } void GetLocalMinMax(const CArray<double>& arData, CArray<int>& arPositionsMin, CArray<int>& arPositionsMax) { int nCount = 0; double nMin = 0, nMax = 0; bool bIsMaxF = false; bool bIsMinF = false; for(int nPos = 1; nPos < arData.GetCount() - 1; nPos++) { //Отслеживаем уменьшение. if ((nPos == 1) || (arData[nPos - 1] < arData[nPos])) { nMax = arData[nPos]; bIsMaxF = true; } if ((nPos == 1) || (arData[nPos - 1] > arData[nPos])) { nMin = arData[nPos]; bIsMinF = true; } //Если ранее было обнаружено уменьшение. if(bIsMaxF) { //Отслеживаем увеличение. if ((nPos == arData.GetCount() - 1) || (arData[nPos - 1] > arData[nPos])) { //Очередной локальный max найден. arPositionsMax.Add(nPos); nCount++; if(nCount == 1) nMin = nMax; else if(nMax < nMin) nMin = nMax; bIsMaxF = false; } } if(bIsMinF) { //Отслеживаем увеличение. if ((nPos == arData.GetCount() - 1) || (arData[nPos - 1] < arData[nPos])) { //Очередной локальный минимум найден. arPositionsMin.Add(nPos); nCount++; if(nCount == 1) nMax = nMin; else if(nMin > nMax) nMax = nMin; bIsMinF = false; } } } } void CalcBlocks(int nMinBlockLen, CArray<CBlock>& m_arWidthBlock, double nAvVal, const CArray<double>& arData) { m_arWidthBlock.RemoveAll(); CBlock block; int nSpaces = 0; for (int nPos = 0; nPos < arData.GetCount(); nPos++) { if(arData[nPos] >= nAvVal) { if(block.m_nStartPoin) { block.m_nBlockLen++; nSpaces = 0; } else { block.m_nStartPoin = nPos; block.m_nBlockLen++; nSpaces = 0; } } else { if(block.m_nStartPoin) { if(nSpaces >= nMinBlockLen) { block.m_nEndPoint = nPos - nSpaces; block.m_nBlockLen -= nSpaces; nSpaces = 0; m_arWidthBlock.Add(block); block.Empty(); continue; } nSpaces++; } } } if(block.m_nStartPoin) { block.m_nEndPoint = arData.GetCount() - nSpaces; m_arWidthBlock.Add(block); } } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { IplImage* pFrame = NULL; //Захваченый фрейм IplImage* pGray = NULL; //Фрейм приведенный к серому цвету IplImage* pGrath = NULL; //Тут рисуем графики CFileFind finder; //BOOL bWorking = finder.FindFile(_T("c:/Utils/Работа/Мое/Распознание/Саша/Day/*.*")); BOOL bWorking = finder.FindFile(_T("C:/Users/Я/Desktop/Avto-Control Demo/Images/Day/*.*")); while (bWorking) { bWorking = finder.FindNextFile(); if(!bWorking) break; CStringA strFileName(finder.GetFilePath()); if(finder.IsDots()) continue; TRACE(strFileName.GetString()); TRACE(_T("\n")); pFrame = cvLoadImage(strFileName); if(!pFrame) continue; DWORD dwStart = GetTickCount(); cvSmooth(pFrame, pFrame, CV_GAUSSIAN, 3, 3); //Создаем серое изображение pGray = cvCreateImage(cvGetSize(pFrame), 8, 1); cvConvertImage(pFrame, pGray, CV_BGR2GRAY); //Выравниваем яркость изображения cvEqualizeHist(pGray, pGray); CArray<double> arGraf; AplySobel(pGray, pGray); SummRow(pGray, arGraf); int nMaxPos = GetMaxPosition(arGraf); CArray<double> arFunc; Func(pGray, nMaxPos, arFunc); CArray<double> arSmooth; //GauseSmooth(arFunc, arSmooth); CArray<double> arDif; GetFirstDiff(arFunc, arDif); CArray<int> arMins; CArray<int> arMaxs; GetLocalMinMax(arDif, arMins, arMaxs); int nMaxFromMax = GetMaxPosition(arDif); double nAvValMax = arDif[nMaxFromMax] * 0.2; CArray<CBlock> arBlocks; CalcBlocks(20, arBlocks, nAvValMax, arDif); /* for (int nPos = 0; nPos < arMaxs.GetCount(); nPos++) { nAvValMax += arDif[arMaxs[nPos]]; }*/ //nAvValMax = nAvValMax / arMaxs.GetCount(); //nAvValMax = nAvValMax + nAvValMax * 0.2; pGrath = cvCreateImage(cvGetSize(pFrame), 8, 1); DrawGraf(pFrame, arGraf); CvPoint ptLast = cvPoint(0, nMaxPos); int nCount = 0; // for (int nPos = 0; nPos < arDif.GetCount(); nPos++) // { // //if(arDif[nPos] < nAvValMax) // //{ // // //cvDrawLine(pGrath, cvPoint(nPos, nMaxPos), cvPoint(nPos, nMaxPos - (int)(arDif[nPos])), cvScalar(0), 1); // // continue; // //} // // nCount++; // cvDrawLine(pFrame, cvPoint(nPos, nMaxPos), cvPoint(nPos, nMaxPos + (int)(arDif[nPos] / 5)), cvScalar(0), 1); // ///* // int nPosY = (nMaxPos + (int)arDif[nPos] / 5); // cvDrawLine(pGrath, ptLast, cvPoint(nPos, nPosY), cvScalar(0), 1); // ptLast = cvPoint(nPos, nPosY); //*/ // } for (int nPos = 0; nPos < arBlocks.GetCount(); nPos++) { CBlock &block = arBlocks[nPos]; int nHigh = (int)(block.m_nEndPoint - block.m_nStartPoin) / 9.2; if(arBlocks[nPos].m_nBlockLen < 10 || arBlocks[nPos].m_nBlockLen > 100) continue; cvDrawRect(pFrame, cvPoint(arBlocks[nPos].m_nStartPoin - 10, nMaxPos - nHigh), cvPoint(arBlocks[nPos].m_nEndPoint + 10, nMaxPos + nHigh), cvScalar(255), 2); } std::cout << nCount << " " << GetTickCount() - dwStart << std::endl ; cvNamedWindow("Graf"); cvShowImage("Graf", pFrame); cvReleaseImage(&pGray); cvReleaseImage(&pFrame); cvReleaseImage(&pGrath); char c = cvWaitKey(0); if (c == 27) { break; } } return 0; }
-
Можно ли сделать чтобы информация выводимая поверх постоянно обновляемого jpeg не мигала?
nagoHok replied to вф1's topic in OpenCV
Если говорить о непосредственной обработке и выводе графики на монитор, тогда конечно ГДИ - это динозавр, но что бы распечатать, то теже самые Директы и ОпенДЖэли будут пользовать ГДИ. Мы об одном и томже только с разных сторон -
Можно ли сделать чтобы информация выводимая поверх постоянно обновляемого jpeg не мигала?
nagoHok replied to вф1's topic in OpenCV
От ГДИ не уйти, это унификация всего вывода графики. Тут надо отделить мух от котлет, для чего нужен ГДИ и для чего нужны Директы и ОпенДЖеэли Если первый предоставляет простой механизм для вывода графической информации неважно на какое либо устройство, то вторые это мощные средства для обработки аудио и видио кратко как то так -
пока все в процессе Сразу попутный вопрос, можно ли произвести фильтрацию изначального изображения КИХ фильтром?
-
так ну получается примерно следующее
-
хмм, я тут подумал что будет лучше сделать гистограмму для каждого отдельного "блока" вертикальной гистограммы.
-
Так попробовал срезать значение гистограммы с помощью среднего значения и дисперсии, в принципе результат неплохой, сейчас подошел не посредственно к локализации пластины, что можете посоветовать? Прикладываю 3 картинки, в принципе на изображениях непосредственно от 3 до 5 областей где может находиться номерная пластина, как же выбрать нужную область? Спасибо за рание.
-
MeanShift? а можно про него по конкретнее?
-
ну среднее - я понял что такое, а вот дисперсия? По точнее можно узнать как её готовить?
-
невсегда бывает корректно, порой глобальный максимум многократно превышает локальные, хотя для начала можно развивать и эту идею.
-
а глобальный максимум это я так понимаю наибольший всплеск на гистограмме?
-
Может кто нибудь подскажет алгоритм, как выдилить из всей гисторгаммы следующие скачки (выделил их на рисунке) Я так понимаю это вроде как глобальные максимумы? Спасибо за рание.
-
так, вернулся о5 таки к проекту, удалось сгладить полученую функци, но быстродействие оставляет желать лучшего, с тем учотом что еше надо и локализовать область номерного знака а затем попытаться распознать символы если кому интересна вот реализации сглаживающей функции inline double GausSmooth(double nDist, double nParam, double nParam2) { return exp((-(nDist * nDist)/nParam)) / nParam2; } void SmoothFunc1(const CArray<_Line>& arSrc, CArray<_Line>& arDest) { arDest.RemoveAll(); double nParam = 15.; int nAperture = 50; double nParam1 = 2* (nParam * nParam); double nParam2 = sqrt(2 * CV_PI) * nParam; for(int nPosY = 0; nPosY < arSrc.GetCount() - 1; nPosY++) { _Line line; line = arSrc[nPosY]; for (int nPosX = 0; nPosX < arSrc[nPosY].GetSize() - 1; nPosX++) { double s = 0.; for (int nK = max(nPosX - nAperture, 0); nK < min(arSrc[nPosY].GetSize() - 1, nPosX + nAperture); nK++) { s += arSrc[nPosY].Get(nK) * GausSmooth(abs(nPosX - nK), nParam1, nParam2); } line.SetAt(nPosX, s); } arDest.Add(line); } }