Jump to content
Compvision.ru

nagoHok

Пользователи
  • Content count

    54
  • Joined

  • Last visited

  • Days Won

    1

nagoHok last won the day on August 12 2011

nagoHok had the most liked content!

Community Reputation

4 Новичек

About nagoHok

  • Rank
    Эксперт
  1. Не советую использовать для этого таймер, ибо в карте сообщений системы он стоит самый последний, лучше для этого организовать отдельный поток.
  2. я этими пользуюсь 1.rar
  3. Оч сырой код, но более 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; }
  4. Если говорить о непосредственной обработке и выводе графики на монитор, тогда конечно ГДИ - это динозавр, но что бы распечатать, то теже самые Директы и ОпенДЖэли будут пользовать ГДИ. Мы об одном и томже только с разных сторон
  5. От ГДИ не уйти, это унификация всего вывода графики. Тут надо отделить мух от котлет, для чего нужен ГДИ и для чего нужны Директы и ОпенДЖеэли Если первый предоставляет простой механизм для вывода графической информации неважно на какое либо устройство, то вторые это мощные средства для обработки аудио и видио кратко как то так
  6. пока все в процессе Сразу попутный вопрос, можно ли произвести фильтрацию изначального изображения КИХ фильтром?
  7. так ну получается примерно следующее
  8. хмм, я тут подумал что будет лучше сделать гистограмму для каждого отдельного "блока" вертикальной гистограммы.
  9. Так попробовал срезать значение гистограммы с помощью среднего значения и дисперсии, в принципе результат неплохой, сейчас подошел не посредственно к локализации пластины, что можете посоветовать? Прикладываю 3 картинки, в принципе на изображениях непосредственно от 3 до 5 областей где может находиться номерная пластина, как же выбрать нужную область? Спасибо за рание.
  10. MeanShift? а можно про него по конкретнее?
  11. ну среднее - я понял что такое, а вот дисперсия? По точнее можно узнать как её готовить?
  12. невсегда бывает корректно, порой глобальный максимум многократно превышает локальные, хотя для начала можно развивать и эту идею.
  13. а глобальный максимум это я так понимаю наибольший всплеск на гистограмме?
  14. Может кто нибудь подскажет алгоритм, как выдилить из всей гисторгаммы следующие скачки (выделил их на рисунке) Я так понимаю это вроде как глобальные максимумы? Спасибо за рание.
  15. так, вернулся о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); } }
×