COIN RECOGNITION - OPENCV
- Mintha egy képet olvasnánk be
- Csak most éppen 30 darabot másodpercenként
- Ezáltal teljesítménycsökkenés
- A program futásának ideje a periféria elérhetősége függvényében
Mat Frame;
VideoCapture cap(0); // alapértelmezett kamerabemenet
if (!cap.isOpened())
{
cout << "Can't open camera."
}
while (true)
{
cap >> Frame;
imshow("Display window - Original", Frame)
//
//További programkód helye
//
char c = (char)waitKey(25);
if((c == 27) or (!cap.isOpened()))
{
break;
}
}
- Szürkeárnyalattá alakítjuk át
- Egyszerű Median Blur
- Visszaadjuk a kapott képet
Mat src = Frame;
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
medianBlur(gray, gray, 5);
return gray;
Hough transzformáció egyik speciális esetét használjuk
vector<Vec3f> circles;
HoughCircles(gray, circles, HOUGH_GRADIENT, 1, gray.rows / 16, 100, 30, 1, 100 ); // utolsó kettő felel a körök minimum és maximum sugarának
return circles;
- Kontúr alapú éldetektálást végzünk
- Alapvetően Hough transzformációnál explicit görbéket keresünk
- Ilyen alakban: F(x, y, a 1 , a 2 , a 3 .... an) = 0
- Körök esetén 3 dimenziós Hough-tér lesz
- Mivel az általános kör képlete x^2 + y^2 = r^2
- Ezt átírva: F(x, y, r) = ax^2 + by^2 - r^2 = 0
- De ez túl erőforrás igényes, így át tudjuk alakítani 2 dimenziósra, ha egy adott méretű kört keresünk →min és maxértéket megadva végig nézzük őket
A HCT által kinyert kör mentén kimetsszük az érmét és eltároljuk
if (circles.size() != 0)
{
Vec3f circ = circles[0];
Mat1b mask(src.size(), uchar(0));
circle(mask, Point(circ[0], circ[1]), circ[2], Scalar(255), FILLED);
Rect bbox(circ[0] - circ[2], circ[1] - circ[2], 2 * circ[2], 2 * circ[2]);
Mat3b res(src.size(), Vec3b(0, 0, 0));
src.copyTo(res, mask);
res = res(bbox);
return res;
}
else
{
Mat image(240, 240, CV_8UC3, Scalar(0, 0, 0));
return image;
}
Detektál körök megjelenítése, rámaszkolva az eredetire
Vec3i c = circles[i];
Point center = Point(c[0], c[1]);
// kör közepe
circle(src, center, 1, Scalar(0, 100, 100), 3, LINE_AA);
// kör körvonala
int radius = c[2];
circle(src, center, radius, Scalar(255, 0, 255), 3, LINE_AA);
- Mintakeresési algoritmus
- Pixelenkénti összehasonlítás
- Visszatérünk egy százalék értékkel
Mat scoreImg;
double maxScore;
matchTemplate(coin, Crop(), scoreImg, TM_SQDIFF_NORMED);
minMaxLoc(scoreImg, 0, &maxScore);
//cout << (1 - maxScore) << endl;
return 1 - maxScore;
- Százalékalapú
- (50% alatt nem fogadjuk el)
vector<double> percent;
percent.push_back(match(_5));
percent.push_back(match(_10));
//...
double sum = 0;
for (int i = 0; i < 6; i++)
{
sum += (percent[i]);
}
if (sum != 0)
{
if ((1 - match(_5) == *max_element(percent.begin(), percent.end())) && *max_element(percent.begin(), percent.end()) > 0.5)
{
cout << "5Ft - " << *max_element(percent.begin(), percent.end()) * 100 << '%' << endl;
}
if ((1 - match(_10) == *max_element(percent.begin(), percent.end())) && *max_element(percent.begin(), percent.end()) > 0.5)
{
cout << "10Ft - " << *max_element(percent.begin(), percent.end()) * 100 << '%' << endl;
}
//...
}