Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

matchShapes for Contour Defects

Hello everyone, I have little experience with OpenCV and hoped that someone here can help me here. The contour data in the following code represent the limit of a plastic part. By comparing the contour, defects of the part should be found. Therefore I read in data and perform the comparison with matchShapes(). Unfortunately, I can only post-process the data, since they do not come from OpenCV. :

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

using namespace cv;
using namespace std;


vector<Point> toCVContour(const vector<double> xPtn, const vector<double> yPtn)
{
    vector<Point> contourOut;
    if (xPtn.size() == yPtn.size())
    {
           for (int i = 0; i < xPtn.size(); i++)
           {
                    cv::Point ptnTmp;
                    int xTmp = int(xPtn[i]);
                    int yTmp = int(yPtn[i]);

                    ptnTmp.x = xTmp;
                    ptnTmp.y = yTmp;
                    contourOut.push_back(ptnTmp);
            }
     }
     return contourOut;
 }

void drawContourPts(Mat& drawing, vector<Point> contourPts)
{
  for (int i = 0; i < contourPts.size(); i++)
  {
    Scalar color = Scalar(255, 255, 255);
    circle(drawing, contourPts[i], 4, color, 1, 8, 0);
  }
    return;
}

int main()
{

vector<double> xPtsT, yPtsT;
// x-Koordinates of Template-Contour
xPtsT = { 1567.0, 1566.0, 1566.0, 1557.0, 1547.0, 1538.0, 1529.0, 1522.0, 1516.0, 1512.0, 1508.0, 1506.0, 1504.0, 1503.0, 1503.0, 1504.0, 1506.0, 1506.0, 1506.0, 1503.0, 1498.0, 1490.0, 1482.0, 1475.0, 1470.0, 1465.0, 1461.0, 1458.0, 1456.0, 1455.0, 1455.0, 1455.0, 1456.0, 1456.0, 1456.0, 1456.0, 1454.0, 1452.0, 1450.0, 1446.0, 1442.0, 1437.0, 1432.0, 1429.0, 1427.0, 1426.0, 1425.0, 1426.0, 1427.0, 1429.0, 1431.0, 1432.0, 1432.0, 1431.0, 1430.0, 1428.0, 1425.0, 1422.0, 1418.0, 1415.0, 1413.0, 1412.0, 1411.0, 1412.0, 1414.0, 1416.0, 1419.0, 1420.0, 1421.0, 1422.0, 1421.0, 1420.0, 1419.0, 1416.0, 1413.0, 1410.0, 1409.0, 1408.0, 1408.0, 1409.0, 1410.0, 1413.0, 1417.0, 1418.0, 1421.0, 1422.0, 1423.0, 1422.0, 1422.0, 1420.0, 1417.0, 1415.0, 1413.0, 1412.0, 1412.0, 1413.0, 1414.0, 1417.0, 1420.0, 1423.0, 1425.0, 1427.0, 1428.0, 1428.0, 1428.0, 1427.0, 1425.0, 1422.0, 1420.0, 1419.0, 1419.0, 1419.0, 1421.0, 1423.0, 1426.0, 1428.0, 1430.0, 1432.0, 1432.0, 1432.0, 1431.0, 1430.0, 1427.0, 1424.0, 1422.0, 1421.0, 1421.0, 1421.0, 1422.0, 1425.0, 1428.0, 1432.0, 1434.0, 1437.0, 1438.0, 1439.0, 1439.0, 1439.0, 1437.0, 1435.0, 1433.0, 1432.0, 1432.0, 1433.0, 1434.0, 1437.0, 1440.0, 1445.0, 1448.0, 1451.0, 1454.0, 1456.0, 1456.0, 1456.0, 1456.0, 1455.0, 1453.0, 1452.0, 1452.0, 1453.0, 1455.0, 1458.0, 1461.0, 1466.0, 1471.0, 1474.0, 1478.0, 1480.0, 1482.0, 1483.0, 1483.0, 1483.0, 1482.0, 1481.0, 1481.0, 1482.0, 1484.0, 1487.0, 1491.0, 1496.0, 1502.0, 1506.0, 1510.0, 1514.0, 1516.0, 1518.0, 1519.0, 1519.0, 1519.0, 1518.0, 1519.0, 1520.0, 1523.0, 1526.0, 1530.0, 1535.0, 1541.0, 1547.0, 1552.0, 1556.0, 1560.0, 1562.0, 1564.0, 1565.0, 1565.0, 1566.0, 1566.0, 1568.0, 1571.0, 1574.0, 1578.0, 1584.0, 1590.0, 1596.0, 1600.0 };

// y-Koordinates of Template-Contour
yPtsT = { 251.0, 261.0, 271.0, 277.0, 284.0, 293.0, 302.0, 312.0, 322.0, 332.0, 342.0, 352.0, 362.0, 372.0, 382.0, 392.0, 402.0, 412.0, 422.0, 432.0, 442.0, 452.0, 462.0, 472.0, 482.0, 492.0, 502.0, 512.0, 522.0, 532.0, 542.0, 552.0, 562.0, 572.0, 582.0, 592.0, 602.0, 612.0, 622.0, 632.0, 642.0, 652.0, 662.0, 672.0, 682.0, 692.0, 702.0, 712.0, 722.0, 732.0, 742.0, 752.0, 762.0, 772.0, 782.0, 792.0, 802.0, 812.0, 822.0, 832.0, 842.0, 852.0, 862.0, 872.0, 882.0, 892.0, 902.0, 912.0, 922.0, 932.0, 942.0, 952.0, 962.0, 972.0, 982.0, 992.0, 1002.0, 1012.0, 1022.0, 1032.0, 1042.0, 1052.0, 1062.0, 1072.0, 1082.0, 1092.0, 1102.0, 1112.0, 1122.0, 1132.0, 1142.0, 1152.0, 1162.0, 1172.0, 1182.0, 1192.0, 1202.0, 1212.0, 1222.0, 1232.0, 1242.0, 1252.0, 1262.0, 1272.0, 1282.0, 1292.0, 1302.0, 1312.0, 1323.0, 1333.0, 1343.0, 1353.0, 1363.0, 1373.0, 1383.0, 1393.0, 1403.0, 1413.0, 1423.0, 1433.0, 1443.0, 1453.0, 1463.0, 1473.0, 1483.0, 1493.0, 1503.0, 1513.0, 1523.0, 1533.0, 1543.0, 1553.0, 1563.0, 1573.0, 1583.0, 1593.0, 1603.0, 1613.0, 1623.0, 1633.0, 1643.0, 1653.0, 1663.0, 1673.0, 1683.0, 1693.0, 1703.0, 1713.0, 1723.0, 1733.0, 1743.0, 1753.0, 1763.0, 1773.0, 1783.0, 1793.0, 1803.0, 1813.0, 1823.0, 1833.0, 1843.0, 1853.0, 1863.0, 1873.0, 1883.0, 1893.0, 1903.0, 1913.0, 1923.0, 1933.0, 1943.0, 1953.0, 1963.0, 1973.0, 1983.0, 1993.0, 2003.0, 2013.0, 2023.0, 2033.0, 2043.0, 2053.0, 2063.0, 2073.0, 2083.0, 2093.0, 2103.0, 2113.0, 2123.0, 2133.0, 2143.0, 2153.0, 2163.0, 2173.0, 2183.0, 2193.0, 2203.0, 2213.0, 2223.0, 2233.0, 2243.0, 2253.0, 2263.0, 2273.0, 2283.0, 2293.0, 2303.0, 2313.0, 2323.0, 2333.0, 2343.0, 2353.0, 2363.0, 2373.0, 2383.0 };

// Vector of x-Koordinates from Query-Contour
vector<vector<double>> xQ;
// Vector of y-Koordinates from Query-Contour
vector<vector<double>> yQ;

vector<double> xTmp, yTmp;
// Good Contour: Low Score
xTmp = {1360.0, 1360.0, 1359.0, 1354.0, 1344.0, 1334.0, 1325.0, 1317.0, 1310.0, 1304.0, 1300.0, 1296.0, 1294.0, 1292.0, 1292.0, 1292.0, 1292.0, 1294.0, 1294.0, 1293.0, 1290.0, 1285.0, 1277.0, 1270.0, 1263.0, 1257.0, 1253.0, 1249.0, 1246.0, 1244.0, 1243.0, 1243.0, 1243.0, 1244.0, 1244.0, 1244.0, 1244.0, 1242.0, 1240.0, 1237.0, 1234.0, 1229.0, 1225.0, 1221.0, 1218.0, 1216.0, 1214.0, 1214.0, 1215.0, 1216.0, 1218.0, 1219.0, 1220.0, 1220.0, 1220.0, 1218.0, 1216.0, 1214.0, 1210.0, 1207.0, 1204.0, 1202.0, 1201.0, 1201.0, 1201.0, 1203.0, 1205.0, 1208.0, 1209.0, 1210.0, 1211.0, 1210.0, 1209.0, 1207.0, 1205.0, 1202.0, 1199.0, 1198.0, 1197.0, 1197.0, 1198.0, 1200.0, 1203.0, 1206.0, 1209.0, 1211.0, 1212.0, 1212.0, 1212.0, 1211.0, 1209.0, 1206.0, 1204.0, 1202.0, 1201.0, 1202.0, 1202.0, 1204.0, 1207.0, 1210.0, 1213.0, 1216.0, 1217.0, 1218.0, 1218.0, 1217.0, 1216.0, 1214.0, 1211.0, 1210.0, 1209.0, 1209.0, 1209.0, 1211.0, 1213.0, 1216.0, 1219.0, 1221.0, 1221.0, 1222.0, 1222.0, 1222.0, 1219.0, 1216.0, 1214.0, 1212.0, 1211.0, 1210.0, 1211.0, 1213.0, 1215.0, 1218.0, 1222.0, 1225.0, 1227.0, 1228.0, 1228.0, 1228.0, 1228.0, 1226.0, 1224.0, 1222.0, 1222.0, 1222.0, 1222.0, 1224.0, 1227.0, 1231.0, 1235.0, 1238.0, 1241.0, 1243.0, 1245.0, 1245.0, 1245.0, 1244.0, 1243.0, 1242.0, 1241.0, 1241.0, 1243.0, 1245.0, 1247.0, 1251.0, 1256.0, 1260.0, 1264.0, 1267.0, 1269.0, 1270.0, 1271.0, 1271.0, 1270.0, 1270.0, 1270.0, 1270.0, 1272.0, 1274.0, 1277.0, 1281.0, 1286.0, 1291.0, 1296.0, 1299.0, 1302.0, 1305.0, 1306.0, 1307.0, 1307.0, 1307.0, 1307.0, 1308.0, 1310.0, 1312.0, 1316.0, 1320.0, 1325.0, 1332.0, 1337.0, 1341.0, 1345.0, 1348.0, 1351.0, 1352.0, 1353.0, 1354.0, 1354.0, 1356.0, 1358.0, 1361.0, 1364.0, 1369.0, 1375.0, 1381.0, 1386.0};
xQ.push_back(xTmp);
yTmp = {254.0, 264.0, 274.0, 281.0, 287.0, 295.0, 303.0, 313.0, 323.0, 333.0, 343.0, 353.0, 363.0, 373.0, 383.0, 393.0, 403.0, 413.0, 423.0, 433.0, 443.0, 453.0, 462.0, 472.0, 482.0, 492.0, 502.0, 512.0, 522.0, 532.0, 542.0, 552.0, 562.0, 572.0, 582.0, 592.0, 602.0, 612.0, 622.0, 632.0, 642.0, 652.0, 662.0, 672.0, 682.0, 692.0, 702.0, 712.0, 722.0, 732.0, 742.0, 752.0, 762.0, 772.0, 782.0, 792.0, 802.0, 812.0, 822.0, 832.0, 842.0, 852.0, 862.0, 872.0, 882.0, 892.0, 902.0, 912.0, 922.0, 932.0, 942.0, 952.0, 962.0, 972.0, 982.0, 992.0, 1002.0, 1012.0, 1022.0, 1032.0, 1042.0, 1052.0, 1062.0, 1072.0, 1082.0, 1092.0, 1102.0, 1112.0, 1122.0, 1132.0, 1142.0, 1152.0, 1162.0, 1172.0, 1182.0, 1192.0, 1202.0, 1212.0, 1222.0, 1232.0, 1242.0, 1252.0, 1262.0, 1272.0, 1282.0, 1292.0, 1302.0, 1312.0, 1323.0, 1333.0, 1343.0, 1353.0, 1363.0, 1373.0, 1383.0, 1393.0, 1403.0, 1413.0, 1423.0, 1433.0, 1443.0, 1453.0, 1463.0, 1473.0, 1483.0, 1493.0, 1503.0, 1513.0, 1523.0, 1533.0, 1543.0, 1553.0, 1563.0, 1573.0, 1583.0, 1593.0, 1603.0, 1613.0, 1623.0, 1633.0, 1643.0, 1653.0, 1663.0, 1673.0, 1683.0, 1693.0, 1703.0, 1713.0, 1723.0, 1733.0, 1743.0, 1753.0, 1763.0, 1773.0, 1783.0, 1793.0, 1803.0, 1813.0, 1823.0, 1833.0, 1843.0, 1853.0, 1863.0, 1873.0, 1883.0, 1893.0, 1903.0, 1913.0, 1923.0, 1933.0, 1943.0, 1953.0, 1963.0, 1973.0, 1983.0, 1993.0, 2003.0, 2013.0, 2023.0, 2033.0, 2043.0, 2053.0, 2063.0, 2073.0, 2083.0, 2093.0, 2103.0, 2113.0, 2123.0, 2133.0, 2143.0, 2153.0, 2163.0, 2173.0, 2183.0, 2193.0, 2203.0, 2213.0, 2223.0, 2233.0, 2243.0, 2253.0, 2263.0, 2273.0, 2283.0, 2293.0, 2303.0, 2313.0, 2323.0, 2333.0, 2343.0, 2353.0, 2363.0, 2373.0, 2383.0};
yQ.push_back(yTmp);

// Good Contour: Low Score
xTmp = { 1467.0, 1467.0, 1467.0, 1457.0, 1447.0, 1438.0, 1430.0, 1423.0, 1417.0, 1412.0, 1409.0, 1406.0, 1404.0, 1403.0, 1404.0, 1404.0, 1405.0, 1406.0, 1405.0, 1402.0, 1397.0, 1390.0, 1381.0, 1374.0, 1368.0, 1363.0, 1360.0, 1357.0, 1355.0, 1354.0, 1353.0, 1353.0, 1354.0, 1355.0, 1355.0, 1354.0, 1353.0, 1350.0, 1348.0, 1344.0, 1339.0, 1334.0, 1330.0, 1327.0, 1324.0, 1323.0, 1322.0, 1323.0, 1324.0, 1326.0, 1328.0, 1328.0, 1328.0, 1328.0, 1327.0, 1325.0, 1322.0, 1318.0, 1315.0, 1311.0, 1309.0, 1308.0, 1307.0, 1308.0, 1310.0, 1312.0, 1314.0, 1316.0, 1317.0, 1317.0, 1317.0, 1316.0, 1314.0, 1312.0, 1309.0, 1306.0, 1304.0, 1303.0, 1303.0, 1304.0, 1305.0, 1308.0, 1311.0, 1314.0, 1315.0, 1317.0, 1317.0, 1317.0, 1316.0, 1315.0, 1312.0, 1310.0, 1308.0, 1307.0, 1306.0, 1307.0, 1308.0, 1311.0, 1314.0, 1317.0, 1319.0, 1321.0, 1322.0, 1322.0, 1322.0, 1321.0, 1319.0, 1316.0, 1314.0, 1313.0, 1312.0, 1313.0, 1314.0, 1316.0, 1319.0, 1321.0, 1323.0, 1325.0, 1325.0, 1325.0, 1324.0, 1323.0, 1321.0, 1318.0, 1316.0, 1314.0, 1314.0, 1314.0, 1315.0, 1317.0, 1320.0, 1324.0, 1327.0, 1329.0, 1331.0, 1332.0, 1332.0, 1332.0, 1331.0, 1329.0, 1327.0, 1326.0, 1325.0, 1325.0, 1327.0, 1329.0, 1332.0, 1336.0, 1340.0, 1343.0, 1346.0, 1347.0, 1349.0, 1349.0, 1349.0, 1348.0, 1346.0, 1345.0, 1345.0, 1346.0, 1347.0, 1349.0, 1353.0, 1357.0, 1362.0, 1366.0, 1369.0, 1372.0, 1373.0, 1375.0, 1375.0, 1375.0, 1374.0, 1373.0, 1373.0, 1374.0, 1376.0, 1378.0, 1382.0, 1387.0, 1392.0, 1397.0, 1401.0, 1405.0, 1407.0, 1409.0, 1411.0, 1411.0, 1411.0, 1411.0, 1411.0, 1412.0, 1414.0, 1416.0, 1420.0, 1425.0, 1431.0, 1438.0, 1443.0, 1447.0, 1451.0, 1453.0, 1455.0, 1457.0, 1457.0, 1457.0, 1458.0, 1459.0, 1461.0, 1465.0, 1469.0, 1474.0, 1480.0, 1486.0, 1491.0 };
xQ.push_back(xTmp);
yTmp = { 251.0, 261.0, 271.0, 277.0, 284.0, 292.0, 301.0, 311.0, 321.0, 331.0, 341.0, 351.0, 361.0, 371.0, 381.0, 391.0, 401.0, 411.0, 421.0, 431.0, 441.0, 451.0, 461.0, 471.0, 481.0, 491.0, 501.0, 511.0, 521.0, 531.0, 541.0, 551.0, 561.0, 571.0, 581.0, 591.0, 601.0, 611.0, 621.0, 631.0, 641.0, 651.0, 661.0, 671.0, 681.0, 691.0, 701.0, 711.0, 721.0, 731.0, 741.0, 751.0, 761.0, 771.0, 781.0, 791.0, 801.0, 811.0, 821.0, 831.0, 841.0, 851.0, 861.0, 871.0, 881.0, 891.0, 901.0, 911.0, 921.0, 931.0, 941.0, 951.0, 961.0, 971.0, 981.0, 991.0, 1001.0, 1011.0, 1021.0, 1031.0, 1041.0, 1051.0, 1061.0, 1071.0, 1081.0, 1091.0, 1101.0, 1111.0, 1121.0, 1131.0, 1141.0, 1151.0, 1161.0, 1171.0, 1181.0, 1191.0, 1201.0, 1211.0, 1221.0, 1231.0, 1241.0, 1251.0, 1261.0, 1271.0, 1281.0, 1291.0, 1301.0, 1311.0, 1322.0, 1332.0, 1342.0, 1352.0, 1362.0, 1372.0, 1382.0, 1392.0, 1402.0, 1412.0, 1422.0, 1432.0, 1442.0, 1452.0, 1462.0, 1472.0, 1482.0, 1492.0, 1502.0, 1512.0, 1522.0, 1532.0, 1542.0, 1552.0, 1562.0, 1572.0, 1582.0, 1592.0, 1602.0, 1612.0, 1622.0, 1632.0, 1642.0, 1652.0, 1662.0, 1672.0, 1682.0, 1692.0, 1702.0, 1712.0, 1722.0, 1732.0, 1742.0, 1752.0, 1762.0, 1772.0, 1782.0, 1792.0, 1802.0, 1812.0, 1822.0, 1832.0, 1842.0, 1852.0, 1862.0, 1872.0, 1882.0, 1892.0, 1902.0, 1912.0, 1922.0, 1932.0, 1942.0, 1952.0, 1962.0, 1972.0, 1982.0, 1992.0, 2002.0, 2012.0, 2022.0, 2032.0, 2042.0, 2052.0, 2062.0, 2072.0, 2082.0, 2092.0, 2102.0, 2112.0, 2122.0, 2132.0, 2142.0, 2152.0, 2162.0, 2172.0, 2182.0, 2192.0, 2202.0, 2212.0, 2222.0, 2232.0, 2242.0, 2252.0, 2262.0, 2272.0, 2282.0, 2292.0, 2302.0, 2312.0, 2322.0, 2332.0, 2342.0, 2352.0, 2362.0, 2372.0, 2382.0 };
yQ.push_back(yTmp);

xTmp = { 1484.0, 1483.0, 1483.0, 1473.0, 1463.0, 1453.0, 1444.0, 1436.0, 1430.0, 1425.0, 1421.0, 1418.0, 1416.0, 1415.0, 1415.0, 1415.0, 1417.0, 1417.0, 1416.0, 1413.0, 1408.0, 1401.0, 1393.0, 1386.0, 1380.0, 1375.0, 1371.0, 1368.0, 1366.0, 1365.0, 1364.0, 1365.0, 1365.0, 1366.0, 1366.0, 1365.0, 1364.0, 1362.0, 1359.0, 1355.0, 1351.0, 1346.0, 1342.0, 1339.0, 1336.0, 1335.0, 1335.0, 1336.0, 1337.0, 1339.0, 1341.0, 1342.0, 1342.0, 1341.0, 1339.0, 1336.0, 1333.0, 1330.0, 1326.0, 1323.0, 1321.0, 1320.0, 1320.0, 1321.0, 1323.0, 1325.0, 1327.0, 1328.0, 1329.0, 1329.0, 1328.0, 1327.0, 1325.0, 1322.0, 1319.0, 1317.0, 1316.0, 1315.0, 1315.0, 1316.0, 1319.0, 1321.0, 1324.0, 1326.0, 1327.0, 1328.0, 1328.0, 1328.0, 1326.0, 1324.0, 1322.0, 1320.0, 1318.0, 1318.0, 1318.0, 1319.0, 1321.0, 1324.0, 1327.0, 1329.0, 1331.0, 1332.0, 1332.0, 1332.0, 1331.0, 1330.0, 1328.0, 1326.0, 1324.0, 1323.0, 1323.0, 1324.0, 1326.0, 1329.0, 1331.0, 1333.0, 1335.0, 1335.0, 1335.0, 1334.0, 1333.0, 1331.0, 1328.0, 1326.0, 1324.0, 1324.0, 1324.0, 1325.0, 1327.0, 1330.0, 1333.0, 1336.0, 1338.0, 1340.0, 1341.0, 1341.0, 1341.0, 1340.0, 1338.0, 1336.0, 1335.0, 1334.0, 1335.0, 1336.0, 1338.0, 1342.0, 1346.0, 1349.0, 1352.0, 1355.0, 1356.0, 1357.0, 1358.0, 1357.0, 1356.0, 1355.0, 1354.0, 1354.0, 1354.0, 1356.0, 1358.0, 1362.0, 1366.0, 1371.0, 1374.0, 1377.0, 1380.0, 1381.0, 1382.0, 1383.0, 1382.0, 1381.0, 1381.0, 1381.0, 1382.0, 1384.0, 1387.0, 1390.0, 1395.0, 1401.0, 1405.0, 1409.0, 1412.0, 1415.0, 1416.0, 1417.0, 1417.0, 1417.0, 1417.0, 1417.0, 1419.0, 1421.0, 1424.0, 1428.0, 1433.0, 1439.0, 1445.0, 1450.0, 1454.0, 1457.0, 1459.0, 1461.0, 1462.0, 1462.0, 1462.0, 1463.0, 1465.0, 1467.0, 1471.0, 1475.0, 1480.0, 1486.0, 1491.0, 1496.0, 1500.0 };
xQ.push_back(xTmp);
yTmp  = { 254.0, 264.0, 274.0, 280.0, 287.0, 295.0, 305.0, 315.0, 325.0, 335.0, 345.0, 355.0, 365.0, 375.0, 385.0, 395.0, 405.0, 415.0, 425.0, 435.0, 445.0, 455.0, 465.0, 475.0, 485.0, 495.0, 505.0, 515.0, 525.0, 535.0, 545.0, 555.0, 565.0, 575.0, 585.0, 595.0, 605.0, 615.0, 625.0, 635.0, 645.0, 655.0, 665.0, 675.0, 685.0, 695.0, 705.0, 715.0, 725.0, 735.0, 745.0, 755.0, 765.0, 775.0, 785.0, 795.0, 805.0, 815.0, 825.0, 835.0, 845.0, 855.0, 865.0, 875.0, 885.0, 895.0, 905.0, 915.0, 925.0, 935.0, 945.0, 955.0, 965.0, 975.0, 985.0, 995.0, 1005.0, 1015.0, 1025.0, 1035.0, 1045.0, 1055.0, 1065.0, 1075.0, 1085.0, 1095.0, 1105.0, 1115.0, 1125.0, 1135.0, 1145.0, 1155.0, 1165.0, 1175.0, 1185.0, 1195.0, 1205.0, 1215.0, 1225.0, 1235.0, 1245.0, 1255.0, 1265.0, 1275.0, 1285.0, 1295.0, 1305.0, 1315.0, 1326.0, 1336.0, 1346.0, 1356.0, 1366.0, 1376.0, 1386.0, 1396.0, 1406.0, 1416.0, 1426.0, 1436.0, 1446.0, 1456.0, 1466.0, 1476.0, 1486.0, 1496.0, 1506.0, 1516.0, 1526.0, 1536.0, 1546.0, 1556.0, 1566.0, 1576.0, 1586.0, 1596.0, 1606.0, 1616.0, 1626.0, 1636.0, 1646.0, 1656.0, 1666.0, 1676.0, 1686.0, 1696.0, 1706.0, 1716.0, 1726.0, 1736.0, 1746.0, 1756.0, 1766.0, 1776.0, 1786.0, 1796.0, 1806.0, 1816.0, 1826.0, 1836.0, 1846.0, 1856.0, 1866.0, 1876.0, 1886.0, 1896.0, 1906.0, 1916.0, 1926.0, 1936.0, 1946.0, 1956.0, 1966.0, 1976.0, 1986.0, 1996.0, 2006.0, 2016.0, 2026.0, 2036.0, 2046.0, 2056.0, 2066.0, 2076.0, 2086.0, 2096.0, 2106.0, 2116.0, 2126.0, 2136.0, 2146.0, 2156.0, 2166.0, 2176.0, 2186.0, 2196.0, 2206.0, 2216.0, 2226.0, 2236.0, 2246.0, 2256.0, 2266.0, 2276.0, 2286.0, 2296.0, 2306.0, 2316.0, 2326.0, 2336.0, 2346.0, 2356.0, 2366.0, 2376.0, 2386.0 };
yQ.push_back(yTmp);

// Bad Contour: high Score
xTmp = { 1468.0, 1465.0, 1465.0, 1467.0, 1458.0, 1449.0, 1442.0, 1434.0, 1428.0, 1423.0, 1419.0, 1416.0, 1415.0, 1414.0, 1414.0, 1415.0, 1416.0, 1419.0, 1421.0, 1423.0, 1423.0, 1421.0, 1417.0, 1412.0, 1406.0, 1401.0, 1397.0, 1395.0, 1393.0, 1393.0, 1395.0, 1398.0, 1402.0, 1407.0, 1414.0, 1422.0, 1428.0, 1434.0, 1437.0, 1434.0, 1430.0, 1427.0, 1430.0, 1432.0, 1433.0, 1434.0, 1435.0, 1435.0, 1436.0, 1438.0, 1440.0, 1442.0, 1442.0, 1442.0, 1440.0, 1438.0, 1436.0, 1432.0, 1428.0, 1423.0, 1419.0, 1415.0, 1413.0, 1411.0, 1411.0, 1411.0, 1411.0, 1412.0, 1413.0, 1412.0, 1412.0, 1411.0, 1409.0, 1405.0, 1401.0, 1395.0, 1389.0, 1383.0, 1379.0, 1375.0, 1370.0, 1367.0, 1365.0, 1364.0, 1364.0, 1364.0, 1364.0, 1363.0, 1361.0, 1359.0, 1356.0, 1353.0, 1348.0, 1344.0, 1341.0, 1338.0, 1336.0, 1335.0, 1335.0, 1337.0, 1339.0, 1341.0, 1343.0, 1345.0, 1345.0, 1345.0, 1345.0, 1344.0, 1342.0, 1339.0, 1337.0, 1335.0, 1333.0, 1333.0, 1333.0, 1334.0, 1336.0, 1338.0, 1339.0, 1341.0, 1341.0, 1341.0, 1340.0, 1339.0, 1337.0, 1334.0, 1331.0, 1329.0, 1327.0, 1327.0, 1327.0, 1328.0, 1330.0, 1333.0, 1336.0, 1338.0, 1340.0, 1341.0, 1342.0, 1341.0, 1340.0, 1339.0, 1337.0, 1335.0, 1334.0, 1333.0, 1334.0, 1335.0, 1338.0, 1341.0, 1345.0, 1348.0, 1351.0, 1353.0, 1354.0, 1355.0, 1355.0, 1354.0, 1353.0, 1351.0, 1350.0, 1350.0, 1351.0, 1353.0, 1355.0, 1359.0, 1363.0, 1367.0, 1371.0, 1374.0, 1376.0, 1377.0, 1378.0, 1378.0, 1378.0, 1377.0, 1376.0, 1376.0, 1377.0, 1379.0, 1382.0, 1385.0, 1390.0, 1396.0, 1400.0, 1404.0, 1407.0, 1409.0, 1411.0, 1412.0, 1412.0, 1412.0, 1411.0, 1412.0, 1413.0, 1415.0, 1418.0, 1422.0, 1426.0, 1432.0, 1438.0, 1443.0, 1447.0, 1451.0, 1453.0, 1455.0, 1456.0, 1456.0, 1456.0, 1457.0, 1458.0, 1461.0, 1464.0, 1468.0, 1473.0, 1479.0, 1484.0, 1489.0 };
xQ.push_back(xTmp);
yTmp = { 259.0, 269.0, 279.0, 289.0, 297.0, 304.0, 312.0, 322.0, 332.0, 342.0, 352.0, 362.0, 372.0, 382.0, 392.0, 402.0, 412.0, 422.0, 432.0, 442.0, 452.0, 462.0, 472.0, 482.0, 492.0, 502.0, 512.0, 522.0, 532.0, 542.0, 552.0, 562.0, 572.0, 582.0, 592.0, 602.0, 612.0, 622.0, 632.0, 637.0, 631.0, 633.0, 643.0, 653.0, 663.0, 673.0, 683.0, 693.0, 703.0, 713.0, 723.0, 733.0, 743.0, 753.0, 763.0, 773.0, 783.0, 793.0, 803.0, 813.0, 823.0, 833.0, 843.0, 853.0, 863.0, 873.0, 883.0, 893.0, 903.0, 913.0, 923.0, 933.0, 943.0, 953.0, 963.0, 973.0, 983.0, 993.0, 1002.0, 1004.0, 1011.0, 1021.0, 1031.0, 1041.0, 1051.0, 1061.0, 1071.0, 1081.0, 1091.0, 1101.0, 1111.0, 1121.0, 1131.0, 1141.0, 1151.0, 1161.0, 1171.0, 1181.0, 1191.0, 1201.0, 1211.0, 1221.0, 1231.0, 1241.0, 1251.0, 1261.0, 1271.0, 1281.0, 1291.0, 1301.0, 1311.0, 1321.0, 1332.0, 1342.0, 1352.0, 1362.0, 1372.0, 1382.0, 1392.0, 1402.0, 1412.0, 1422.0, 1432.0, 1442.0, 1452.0, 1462.0, 1472.0, 1482.0, 1492.0, 1502.0, 1512.0, 1522.0, 1532.0, 1542.0, 1552.0, 1562.0, 1572.0, 1582.0, 1592.0, 1602.0, 1612.0, 1622.0, 1632.0, 1642.0, 1652.0, 1662.0, 1672.0, 1682.0, 1692.0, 1702.0, 1712.0, 1722.0, 1732.0, 1742.0, 1752.0, 1762.0, 1772.0, 1782.0, 1792.0, 1802.0, 1812.0, 1822.0, 1832.0, 1842.0, 1852.0, 1862.0, 1872.0, 1882.0, 1892.0, 1902.0, 1912.0, 1922.0, 1932.0, 1942.0, 1952.0, 1962.0, 1972.0, 1982.0, 1992.0, 2002.0, 2012.0, 2022.0, 2032.0, 2042.0, 2052.0, 2062.0, 2072.0, 2082.0, 2092.0, 2102.0, 2112.0, 2122.0, 2132.0, 2142.0, 2152.0, 2162.0, 2172.0, 2182.0, 2192.0, 2202.0, 2212.0, 2222.0, 2232.0, 2242.0, 2252.0, 2262.0, 2272.0, 2282.0, 2292.0, 2302.0, 2312.0, 2322.0, 2332.0, 2342.0, 2352.0, 2362.0, 2372.0, 2382.0 };
yQ.push_back(yTmp);

// Bad Contour: Low Score
xTmp = { 1607.0, 1603.0, 1602.0, 1604.0, 1603.0, 1596.0, 1588.0, 1580.0, 1575.0, 1571.0, 1568.0, 1566.0, 1565.0, 1565.0, 1566.0, 1566.0, 1566.0, 1568.0, 1569.0, 1571.0, 1572.0, 1573.0, 1573.0, 1572.0, 1572.0, 1571.0, 1569.0, 1568.0, 1566.0, 1563.0, 1561.0, 1558.0, 1555.0, 1552.0, 1549.0, 1545.0, 1542.0, 1539.0, 1534.0, 1528.0, 1520.0, 1512.0, 1506.0, 1501.0, 1497.0, 1494.0, 1488.0, 1482.0, 1478.0, 1477.0, 1477.0, 1477.0, 1478.0, 1478.0, 1477.0, 1476.0, 1475.0, 1473.0, 1478.0, 1480.0, 1482.0, 1483.0, 1484.0, 1484.0, 1483.0, 1483.0, 1484.0, 1486.0, 1489.0, 1489.0, 1489.0, 1490.0, 1490.0, 1489.0, 1489.0, 1487.0, 1484.0, 1481.0, 1479.0, 1474.0, 1470.0, 1467.0, 1466.0, 1465.0, 1465.0, 1466.0, 1467.0, 1470.0, 1472.0, 1474.0, 1475.0, 1475.0, 1475.0, 1474.0, 1472.0, 1470.0, 1467.0, 1464.0, 1462.0, 1461.0, 1461.0, 1461.0, 1464.0, 1467.0, 1470.0, 1473.0, 1475.0, 1476.0, 1477.0, 1476.0, 1476.0, 1475.0, 1473.0, 1471.0, 1468.0, 1467.0, 1467.0, 1468.0, 1469.0, 1472.0, 1475.0, 1479.0, 1482.0, 1485.0, 1488.0, 1489.0, 1489.0, 1488.0, 1487.0, 1486.0, 1484.0, 1483.0, 1483.0, 1484.0, 1486.0, 1489.0, 1493.0, 1497.0, 1491.0, 1491.0, 1494.0, 1496.0, 1499.0, 1501.0, 1502.0, 1502.0, 1495.0, 1490.0, 1487.0, 1484.0, 1482.0, 1483.0, 1488.0, 1487.0, 1486.0, 1488.0, 1492.0, 1498.0, 1502.0, 1499.0, 1497.0, 1493.0, 1492.0, 1489.0, 1492.0, 1494.0, 1497.0, 1499.0, 1499.0, 1502.0, 1501.0, 1503.0, 1501.0, 1503.0, 1499.0, 1496.0, 1496.0, 1494.0, 1492.0, 1491.0, 1486.0, 1485.0, 1486.0, 1488.0, 1492.0, 1498.0, 1503.0, 1509.0, 1512.0, 1514.0, 1515.0, 1516.0, 1517.0, 1516.0, 1515.0, 1514.0, 1512.0, 1511.0, 1511.0, 1512.0, 1514.0, 1517.0, 1520.0, 1525.0, 1529.0, 1533.0, 1536.0, 1538.0, 1540.0, 1541.0, 1541.0, 1540.0, 1539.0, 1539.0, 1538.0, 1539.0, 1541.0, 1544.0, 1548.0, 1552.0, 1558.0, 1562.0, 1566.0, 1570.0, 1572.0, 1574.0, 1575.0, 1575.0, 1575.0, 1575.0, 1575.0, 1576.0, 1578.0, 1580.0, 1584.0, 1588.0, 1594.0, 1600.0, 1605.0, 1610.0, 1613.0, 1616.0, 1618.0, 1620.0, 1621.0, 1621.0, 1621.0, 1622.0, 1624.0, 1627.0, 1630.0, 1635.0, 1640.0 };
xQ.push_back(xTmp);
yTmp = { 246.0, 256.0, 266.0, 276.0, 286.0, 293.0, 301.0, 311.0, 321.0, 331.0, 341.0, 351.0, 361.0, 371.0, 381.0, 391.0, 401.0, 411.0, 421.0, 431.0, 441.0, 451.0, 461.0, 471.0, 481.0, 491.0, 501.0, 511.0, 521.0, 531.0, 541.0, 551.0, 561.0, 571.0, 581.0, 591.0, 601.0, 611.0, 621.0, 631.0, 641.0, 651.0, 661.0, 671.0, 681.0, 691.0, 701.0, 711.0, 721.0, 731.0, 741.0, 751.0, 761.0, 771.0, 781.0, 791.0, 801.0, 811.0, 810.0, 800.0, 790.0, 780.0, 770.0, 760.0, 750.0, 740.0, 730.0, 720.0, 725.0, 735.0, 745.0, 755.0, 765.0, 775.0, 785.0, 795.0, 805.0, 815.0, 825.0, 835.0, 845.0, 855.0, 865.0, 875.0, 885.0, 895.0, 905.0, 915.0, 925.0, 935.0, 945.0, 955.0, 965.0, 975.0, 985.0, 995.0, 1005.0, 1015.0, 1025.0, 1035.0, 1045.0, 1055.0, 1065.0, 1075.0, 1085.0, 1095.0, 1105.0, 1115.0, 1125.0, 1135.0, 1145.0, 1155.0, 1165.0, 1175.0, 1185.0, 1195.0, 1205.0, 1215.0, 1225.0, 1235.0, 1245.0, 1255.0, 1265.0, 1275.0, 1285.0, 1295.0, 1305.0, 1316.0, 1326.0, 1336.0, 1346.0, 1356.0, 1366.0, 1376.0, 1386.0, 1396.0, 1406.0, 1416.0, 1406.0, 1414.0, 1424.0, 1434.0, 1444.0, 1454.0, 1464.0, 1472.0, 1479.0, 1489.0, 1499.0, 1509.0, 1519.0, 1529.0, 1537.0, 1527.0, 1517.0, 1507.0, 1497.0, 1487.0, 1481.0, 1491.0, 1501.0, 1511.0, 1520.0, 1526.0, 1536.0, 1545.0, 1555.0, 1565.0, 1575.0, 1583.0, 1592.0, 1600.0, 1606.0, 1610.0, 1609.0, 1617.0, 1627.0, 1637.0, 1647.0, 1651.0, 1660.0, 1670.0, 1680.0, 1690.0, 1700.0, 1709.0, 1718.0, 1724.0, 1734.0, 1744.0, 1754.0, 1764.0, 1774.0, 1784.0, 1794.0, 1804.0, 1814.0, 1824.0, 1834.0, 1844.0, 1854.0, 1864.0, 1874.0, 1884.0, 1894.0, 1904.0, 1914.0, 1924.0, 1934.0, 1944.0, 1954.0, 1964.0, 1974.0, 1984.0, 1994.0, 2004.0, 2014.0, 2024.0, 2034.0, 2044.0, 2054.0, 2064.0, 2074.0, 2084.0, 2094.0, 2104.0, 2114.0, 2124.0, 2134.0, 2144.0, 2154.0, 2164.0, 2174.0, 2184.0, 2194.0, 2204.0, 2214.0, 2224.0, 2234.0, 2244.0, 2254.0, 2264.0, 2274.0, 2284.0, 2294.0, 2304.0, 2314.0, 2324.0, 2334.0, 2344.0, 2354.0, 2364.0, 2374.0 };
yQ.push_back(yTmp);

// Template Contour
vector<Point> templateContour = toCVContour(xPtsT, yPtsT);
Mat templateImg = Mat::zeros(Size(4000, 3000), CV_64FC1);
drawContourPts(templateImg, templateContour);
resize(templateImg, templateImg, Size(templateImg.cols / 3, templateImg.rows / 3));
imshow("Template", templateImg);

for (int q = 0; q < xQ.size(); q++)
{
    vector<double> xQuery = xQ[q];
    vector<double> yQuery = yQ[q];

    vector<Point> queryContour = toCVContour(xQuery, yQuery);
    Mat queryImg = Mat::zeros(Size(4000, 3000), CV_64FC1);
    drawContourPts(queryImg, queryContour);
    resize(queryImg, queryImg, Size(queryImg.cols / 3, queryImg.rows / 3));

    //Match Shapes
    double score = matchShapes(templateContour, queryContour, CONTOURS_MATCH_I2, 0);

    // Print Score
    cv::putText(queryImg,
        std::to_string(score),
        cv::Point(50, 180), 
        cv::FONT_HERSHEY_COMPLEX_SMALL, 
        3.0, 
        cv::Scalar(255, 255, 255),
        1, // 
        LINE_8, false); 
    imshow("Query with Score", queryImg);
    waitKey();
    string filename = "Res" + to_string(q) + ".jpg";
    //imwrite(filename, queryImg);
}


return 0;
}

As the result images show, this works relatively well for some errors, unfortunately there are also cases where errors have a low score. I could imagine that this is due to the following reasons:

  1. the contours are shifted translationally and do not always start at the same point, maybe this has to be compensated
  2. Judging by moments is not the right tool
  3. The contours are not closed

I would be grateful for your comments or suggestions for an alternative approach.

Good Part with Low Score:

image description

Good Part with Low Score:

image description

Bad Part with High Score

image description

Bad Part with Low Score image description

matchShapes for Contour Defects

Hello everyone, I have little experience with OpenCV and hoped that someone here can help me here. The contour data in the following code represent the limit of a plastic part. By comparing the contour, defects of the part should be found. Therefore I read in data and perform the comparison with matchShapes(). Unfortunately, I can only post-process the data, since they do not come from OpenCV. :

As the result images show, this works relatively well for some errors, unfortunately there are also cases where errors have a low score. I could imagine that this is due to the following reasons:

  1. the contours are shifted translationally and do not always start at the same point, maybe this has to be compensated
  2. Judging by moments is not the right tool
  3. The contours are not closed

I would be grateful for your comments or suggestions for an alternative approach.

Good Part with Low Score:

image description

Good Part with Low Score:

image description

Bad Part with High Score

image description

Bad Part with Low Score image description

Edit: I have found an example of a good part with a score as high as the bad one - maybe this will help to identify the problem:

    xTmp = { 1503.0, 1501.0, 1501.0, 1497.0, 1487.0, 1477.0, 1467.0, 1458.0, 1451.0, 1445.0, 1441.0, 1437.0, 1435.0, 1433.0, 1432.0, 1431.0, 1432.0, 1433.0, 1433.0, 1432.0, 1429.0, 1424.0, 1416.0, 1408.0, 1401.0, 1396.0, 1391.0, 1387.0, 1384.0, 1382.0, 1381.0, 1380.0, 1380.0, 1381.0, 1381.0, 1380.0, 1380.0, 1379.0, 1377.0, 1374.0, 1371.0, 1366.0, 1362.0, 1357.0, 1354.0, 1352.0, 1350.0, 1350.0, 1350.0, 1351.0, 1352.0, 1354.0, 1355.0, 1355.0, 1355.0, 1353.0, 1352.0, 1349.0, 1346.0, 1342.0, 1339.0, 1337.0, 1335.0, 1335.0, 1335.0, 1336.0, 1338.0, 1341.0, 1343.0, 1344.0, 1344.0, 1344.0, 1343.0, 1342.0, 1340.0, 1337.0, 1334.0, 1332.0, 1331.0, 1331.0, 1331.0, 1332.0, 1335.0, 1338.0, 1340.0, 1342.0, 1344.0, 1345.0, 1345.0, 1344.0, 1343.0, 1341.0, 1339.0, 1337.0, 1336.0, 1335.0, 1335.0, 1336.0, 1338.0, 1341.0, 1344.0, 1346.0, 1349.0, 1350.0, 1351.0, 1351.0, 1350.0, 1349.0, 1347.0, 1344.0, 1343.0, 1342.0, 1342.0, 1343.0, 1344.0, 1346.0, 1349.0, 1351.0, 1353.0, 1354.0, 1354.0, 1354.0, 1353.0, 1351.0, 1349.0, 1347.0, 1345.0, 1343.0, 1343.0, 1344.0, 1345.0, 1347.0, 1351.0, 1354.0, 1357.0, 1359.0, 1360.0, 1361.0, 1361.0, 1361.0, 1360.0, 1358.0, 1357.0, 1355.0, 1355.0, 1356.0, 1357.0, 1359.0, 1363.0, 1367.0, 1371.0, 1374.0, 1376.0, 1378.0, 1379.0, 1379.0, 1379.0, 1378.0, 1377.0, 1376.0, 1376.0, 1377.0, 1378.0, 1381.0, 1384.0, 1388.0, 1393.0, 1397.0, 1400.0, 1402.0, 1404.0, 1405.0, 1406.0, 1406.0, 1405.0, 1405.0, 1405.0, 1406.0, 1407.0, 1410.0, 1413.0, 1418.0, 1424.0, 1428.0, 1432.0, 1436.0, 1438.0, 1441.0, 1442.0, 1443.0, 1443.0, 1443.0, 1443.0, 1444.0, 1445.0, 1448.0, 1452.0, 1456.0, 1462.0, 1468.0, 1473.0, 1478.0, 1482.0, 1485.0, 1487.0, 1488.0, 1489.0, 1490.0, 1490.0, 1491.0, 1493.0, 1496.0, 1500.0, 1504.0, 1510.0 };
yTmp = { 237.0, 247.0, 257.0, 265.0, 271.0, 278.0, 287.0, 297.0, 307.0, 317.0, 327.0, 337.0, 347.0, 357.0, 367.0, 377.0, 387.0, 397.0, 407.0, 417.0, 427.0, 437.0, 447.0, 457.0, 467.0, 477.0, 487.0, 497.0, 507.0, 517.0, 527.0, 537.0, 547.0, 557.0, 567.0, 577.0, 587.0, 597.0, 607.0, 617.0, 627.0, 637.0, 647.0, 657.0, 667.0, 677.0, 687.0, 697.0, 707.0, 717.0, 727.0, 737.0, 747.0, 757.0, 767.0, 777.0, 787.0, 797.0, 807.0, 817.0, 827.0, 837.0, 847.0, 857.0, 867.0, 877.0, 887.0, 897.0, 907.0, 917.0, 927.0, 937.0, 947.0, 957.0, 967.0, 977.0, 987.0, 997.0, 1007.0, 1017.0, 1027.0, 1037.0, 1047.0, 1057.0, 1067.0, 1077.0, 1087.0, 1097.0, 1107.0, 1117.0, 1127.0, 1137.0, 1147.0, 1157.0, 1167.0, 1177.0, 1187.0, 1197.0, 1207.0, 1217.0, 1227.0, 1237.0, 1247.0, 1257.0, 1267.0, 1277.0, 1287.0, 1297.0, 1308.0, 1318.0, 1328.0, 1338.0, 1348.0, 1358.0, 1368.0, 1378.0, 1388.0, 1398.0, 1408.0, 1418.0, 1428.0, 1438.0, 1448.0, 1458.0, 1468.0, 1478.0, 1488.0, 1498.0, 1508.0, 1518.0, 1528.0, 1538.0, 1548.0, 1558.0, 1568.0, 1578.0, 1588.0, 1598.0, 1608.0, 1618.0, 1628.0, 1638.0, 1648.0, 1658.0, 1668.0, 1678.0, 1688.0, 1698.0, 1708.0, 1718.0, 1728.0, 1738.0, 1748.0, 1758.0, 1768.0, 1778.0, 1788.0, 1798.0, 1808.0, 1818.0, 1828.0, 1838.0, 1848.0, 1858.0, 1868.0, 1878.0, 1888.0, 1898.0, 1908.0, 1918.0, 1928.0, 1938.0, 1948.0, 1958.0, 1968.0, 1978.0, 1988.0, 1998.0, 2008.0, 2018.0, 2028.0, 2038.0, 2048.0, 2058.0, 2068.0, 2078.0, 2088.0, 2098.0, 2108.0, 2118.0, 2128.0, 2138.0, 2148.0, 2158.0, 2168.0, 2178.0, 2188.0, 2198.0, 2208.0, 2218.0, 2228.0, 2238.0, 2248.0, 2258.0, 2268.0, 2278.0, 2288.0, 2298.0, 2308.0, 2318.0, 2328.0, 2338.0, 2348.0, 2358.0, 2368.0 };

image description

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

using namespace cv;
using namespace std;


vector<Point> toCVContour(const vector<double> xPtn, const vector<double> yPtn)
{
    vector<Point> contourOut;
    if (xPtn.size() == yPtn.size())
    {
           for (int i = 0; i < xPtn.size(); i++)
           {
                    cv::Point ptnTmp;
                    int xTmp = int(xPtn[i]);
                    int yTmp = int(yPtn[i]);

                    ptnTmp.x = xTmp;
                    ptnTmp.y = yTmp;
                    contourOut.push_back(ptnTmp);
            }
     }
     return contourOut;
 }

void drawContourPts(Mat& drawing, vector<Point> contourPts)
{
  for (int i = 0; i < contourPts.size(); i++)
  {
    Scalar color = Scalar(255, 255, 255);
    circle(drawing, contourPts[i], 4, color, 1, 8, 0);
  }
    return;
}

int main()
{

vector<double> xPtsT, yPtsT;
// x-Koordinates of Template-Contour
xPtsT = { 1567.0, 1566.0, 1566.0, 1557.0, 1547.0, 1538.0, 1529.0, 1522.0, 1516.0, 1512.0, 1508.0, 1506.0, 1504.0, 1503.0, 1503.0, 1504.0, 1506.0, 1506.0, 1506.0, 1503.0, 1498.0, 1490.0, 1482.0, 1475.0, 1470.0, 1465.0, 1461.0, 1458.0, 1456.0, 1455.0, 1455.0, 1455.0, 1456.0, 1456.0, 1456.0, 1456.0, 1454.0, 1452.0, 1450.0, 1446.0, 1442.0, 1437.0, 1432.0, 1429.0, 1427.0, 1426.0, 1425.0, 1426.0, 1427.0, 1429.0, 1431.0, 1432.0, 1432.0, 1431.0, 1430.0, 1428.0, 1425.0, 1422.0, 1418.0, 1415.0, 1413.0, 1412.0, 1411.0, 1412.0, 1414.0, 1416.0, 1419.0, 1420.0, 1421.0, 1422.0, 1421.0, 1420.0, 1419.0, 1416.0, 1413.0, 1410.0, 1409.0, 1408.0, 1408.0, 1409.0, 1410.0, 1413.0, 1417.0, 1418.0, 1421.0, 1422.0, 1423.0, 1422.0, 1422.0, 1420.0, 1417.0, 1415.0, 1413.0, 1412.0, 1412.0, 1413.0, 1414.0, 1417.0, 1420.0, 1423.0, 1425.0, 1427.0, 1428.0, 1428.0, 1428.0, 1427.0, 1425.0, 1422.0, 1420.0, 1419.0, 1419.0, 1419.0, 1421.0, 1423.0, 1426.0, 1428.0, 1430.0, 1432.0, 1432.0, 1432.0, 1431.0, 1430.0, 1427.0, 1424.0, 1422.0, 1421.0, 1421.0, 1421.0, 1422.0, 1425.0, 1428.0, 1432.0, 1434.0, 1437.0, 1438.0, 1439.0, 1439.0, 1439.0, 1437.0, 1435.0, 1433.0, 1432.0, 1432.0, 1433.0, 1434.0, 1437.0, 1440.0, 1445.0, 1448.0, 1451.0, 1454.0, 1456.0, 1456.0, 1456.0, 1456.0, 1455.0, 1453.0, 1452.0, 1452.0, 1453.0, 1455.0, 1458.0, 1461.0, 1466.0, 1471.0, 1474.0, 1478.0, 1480.0, 1482.0, 1483.0, 1483.0, 1483.0, 1482.0, 1481.0, 1481.0, 1482.0, 1484.0, 1487.0, 1491.0, 1496.0, 1502.0, 1506.0, 1510.0, 1514.0, 1516.0, 1518.0, 1519.0, 1519.0, 1519.0, 1518.0, 1519.0, 1520.0, 1523.0, 1526.0, 1530.0, 1535.0, 1541.0, 1547.0, 1552.0, 1556.0, 1560.0, 1562.0, 1564.0, 1565.0, 1565.0, 1566.0, 1566.0, 1568.0, 1571.0, 1574.0, 1578.0, 1584.0, 1590.0, 1596.0, 1600.0 };

// y-Koordinates of Template-Contour
yPtsT = { 251.0, 261.0, 271.0, 277.0, 284.0, 293.0, 302.0, 312.0, 322.0, 332.0, 342.0, 352.0, 362.0, 372.0, 382.0, 392.0, 402.0, 412.0, 422.0, 432.0, 442.0, 452.0, 462.0, 472.0, 482.0, 492.0, 502.0, 512.0, 522.0, 532.0, 542.0, 552.0, 562.0, 572.0, 582.0, 592.0, 602.0, 612.0, 622.0, 632.0, 642.0, 652.0, 662.0, 672.0, 682.0, 692.0, 702.0, 712.0, 722.0, 732.0, 742.0, 752.0, 762.0, 772.0, 782.0, 792.0, 802.0, 812.0, 822.0, 832.0, 842.0, 852.0, 862.0, 872.0, 882.0, 892.0, 902.0, 912.0, 922.0, 932.0, 942.0, 952.0, 962.0, 972.0, 982.0, 992.0, 1002.0, 1012.0, 1022.0, 1032.0, 1042.0, 1052.0, 1062.0, 1072.0, 1082.0, 1092.0, 1102.0, 1112.0, 1122.0, 1132.0, 1142.0, 1152.0, 1162.0, 1172.0, 1182.0, 1192.0, 1202.0, 1212.0, 1222.0, 1232.0, 1242.0, 1252.0, 1262.0, 1272.0, 1282.0, 1292.0, 1302.0, 1312.0, 1323.0, 1333.0, 1343.0, 1353.0, 1363.0, 1373.0, 1383.0, 1393.0, 1403.0, 1413.0, 1423.0, 1433.0, 1443.0, 1453.0, 1463.0, 1473.0, 1483.0, 1493.0, 1503.0, 1513.0, 1523.0, 1533.0, 1543.0, 1553.0, 1563.0, 1573.0, 1583.0, 1593.0, 1603.0, 1613.0, 1623.0, 1633.0, 1643.0, 1653.0, 1663.0, 1673.0, 1683.0, 1693.0, 1703.0, 1713.0, 1723.0, 1733.0, 1743.0, 1753.0, 1763.0, 1773.0, 1783.0, 1793.0, 1803.0, 1813.0, 1823.0, 1833.0, 1843.0, 1853.0, 1863.0, 1873.0, 1883.0, 1893.0, 1903.0, 1913.0, 1923.0, 1933.0, 1943.0, 1953.0, 1963.0, 1973.0, 1983.0, 1993.0, 2003.0, 2013.0, 2023.0, 2033.0, 2043.0, 2053.0, 2063.0, 2073.0, 2083.0, 2093.0, 2103.0, 2113.0, 2123.0, 2133.0, 2143.0, 2153.0, 2163.0, 2173.0, 2183.0, 2193.0, 2203.0, 2213.0, 2223.0, 2233.0, 2243.0, 2253.0, 2263.0, 2273.0, 2283.0, 2293.0, 2303.0, 2313.0, 2323.0, 2333.0, 2343.0, 2353.0, 2363.0, 2373.0, 2383.0 };

// Vector of x-Koordinates from Query-Contour
vector<vector<double>> xQ;
// Vector of y-Koordinates from Query-Contour
vector<vector<double>> yQ;

vector<double> xTmp, yTmp;
// Good Contour: Low Score
xTmp = {1360.0, 1360.0, 1359.0, 1354.0, 1344.0, 1334.0, 1325.0, 1317.0, 1310.0, 1304.0, 1300.0, 1296.0, 1294.0, 1292.0, 1292.0, 1292.0, 1292.0, 1294.0, 1294.0, 1293.0, 1290.0, 1285.0, 1277.0, 1270.0, 1263.0, 1257.0, 1253.0, 1249.0, 1246.0, 1244.0, 1243.0, 1243.0, 1243.0, 1244.0, 1244.0, 1244.0, 1244.0, 1242.0, 1240.0, 1237.0, 1234.0, 1229.0, 1225.0, 1221.0, 1218.0, 1216.0, 1214.0, 1214.0, 1215.0, 1216.0, 1218.0, 1219.0, 1220.0, 1220.0, 1220.0, 1218.0, 1216.0, 1214.0, 1210.0, 1207.0, 1204.0, 1202.0, 1201.0, 1201.0, 1201.0, 1203.0, 1205.0, 1208.0, 1209.0, 1210.0, 1211.0, 1210.0, 1209.0, 1207.0, 1205.0, 1202.0, 1199.0, 1198.0, 1197.0, 1197.0, 1198.0, 1200.0, 1203.0, 1206.0, 1209.0, 1211.0, 1212.0, 1212.0, 1212.0, 1211.0, 1209.0, 1206.0, 1204.0, 1202.0, 1201.0, 1202.0, 1202.0, 1204.0, 1207.0, 1210.0, 1213.0, 1216.0, 1217.0, 1218.0, 1218.0, 1217.0, 1216.0, 1214.0, 1211.0, 1210.0, 1209.0, 1209.0, 1209.0, 1211.0, 1213.0, 1216.0, 1219.0, 1221.0, 1221.0, 1222.0, 1222.0, 1222.0, 1219.0, 1216.0, 1214.0, 1212.0, 1211.0, 1210.0, 1211.0, 1213.0, 1215.0, 1218.0, 1222.0, 1225.0, 1227.0, 1228.0, 1228.0, 1228.0, 1228.0, 1226.0, 1224.0, 1222.0, 1222.0, 1222.0, 1222.0, 1224.0, 1227.0, 1231.0, 1235.0, 1238.0, 1241.0, 1243.0, 1245.0, 1245.0, 1245.0, 1244.0, 1243.0, 1242.0, 1241.0, 1241.0, 1243.0, 1245.0, 1247.0, 1251.0, 1256.0, 1260.0, 1264.0, 1267.0, 1269.0, 1270.0, 1271.0, 1271.0, 1270.0, 1270.0, 1270.0, 1270.0, 1272.0, 1274.0, 1277.0, 1281.0, 1286.0, 1291.0, 1296.0, 1299.0, 1302.0, 1305.0, 1306.0, 1307.0, 1307.0, 1307.0, 1307.0, 1308.0, 1310.0, 1312.0, 1316.0, 1320.0, 1325.0, 1332.0, 1337.0, 1341.0, 1345.0, 1348.0, 1351.0, 1352.0, 1353.0, 1354.0, 1354.0, 1356.0, 1358.0, 1361.0, 1364.0, 1369.0, 1375.0, 1381.0, 1386.0};
xQ.push_back(xTmp);
yTmp = {254.0, 264.0, 274.0, 281.0, 287.0, 295.0, 303.0, 313.0, 323.0, 333.0, 343.0, 353.0, 363.0, 373.0, 383.0, 393.0, 403.0, 413.0, 423.0, 433.0, 443.0, 453.0, 462.0, 472.0, 482.0, 492.0, 502.0, 512.0, 522.0, 532.0, 542.0, 552.0, 562.0, 572.0, 582.0, 592.0, 602.0, 612.0, 622.0, 632.0, 642.0, 652.0, 662.0, 672.0, 682.0, 692.0, 702.0, 712.0, 722.0, 732.0, 742.0, 752.0, 762.0, 772.0, 782.0, 792.0, 802.0, 812.0, 822.0, 832.0, 842.0, 852.0, 862.0, 872.0, 882.0, 892.0, 902.0, 912.0, 922.0, 932.0, 942.0, 952.0, 962.0, 972.0, 982.0, 992.0, 1002.0, 1012.0, 1022.0, 1032.0, 1042.0, 1052.0, 1062.0, 1072.0, 1082.0, 1092.0, 1102.0, 1112.0, 1122.0, 1132.0, 1142.0, 1152.0, 1162.0, 1172.0, 1182.0, 1192.0, 1202.0, 1212.0, 1222.0, 1232.0, 1242.0, 1252.0, 1262.0, 1272.0, 1282.0, 1292.0, 1302.0, 1312.0, 1323.0, 1333.0, 1343.0, 1353.0, 1363.0, 1373.0, 1383.0, 1393.0, 1403.0, 1413.0, 1423.0, 1433.0, 1443.0, 1453.0, 1463.0, 1473.0, 1483.0, 1493.0, 1503.0, 1513.0, 1523.0, 1533.0, 1543.0, 1553.0, 1563.0, 1573.0, 1583.0, 1593.0, 1603.0, 1613.0, 1623.0, 1633.0, 1643.0, 1653.0, 1663.0, 1673.0, 1683.0, 1693.0, 1703.0, 1713.0, 1723.0, 1733.0, 1743.0, 1753.0, 1763.0, 1773.0, 1783.0, 1793.0, 1803.0, 1813.0, 1823.0, 1833.0, 1843.0, 1853.0, 1863.0, 1873.0, 1883.0, 1893.0, 1903.0, 1913.0, 1923.0, 1933.0, 1943.0, 1953.0, 1963.0, 1973.0, 1983.0, 1993.0, 2003.0, 2013.0, 2023.0, 2033.0, 2043.0, 2053.0, 2063.0, 2073.0, 2083.0, 2093.0, 2103.0, 2113.0, 2123.0, 2133.0, 2143.0, 2153.0, 2163.0, 2173.0, 2183.0, 2193.0, 2203.0, 2213.0, 2223.0, 2233.0, 2243.0, 2253.0, 2263.0, 2273.0, 2283.0, 2293.0, 2303.0, 2313.0, 2323.0, 2333.0, 2343.0, 2353.0, 2363.0, 2373.0, 2383.0};
yQ.push_back(yTmp);

// Good Contour: Low Score
xTmp = { 1467.0, 1467.0, 1467.0, 1457.0, 1447.0, 1438.0, 1430.0, 1423.0, 1417.0, 1412.0, 1409.0, 1406.0, 1404.0, 1403.0, 1404.0, 1404.0, 1405.0, 1406.0, 1405.0, 1402.0, 1397.0, 1390.0, 1381.0, 1374.0, 1368.0, 1363.0, 1360.0, 1357.0, 1355.0, 1354.0, 1353.0, 1353.0, 1354.0, 1355.0, 1355.0, 1354.0, 1353.0, 1350.0, 1348.0, 1344.0, 1339.0, 1334.0, 1330.0, 1327.0, 1324.0, 1323.0, 1322.0, 1323.0, 1324.0, 1326.0, 1328.0, 1328.0, 1328.0, 1328.0, 1327.0, 1325.0, 1322.0, 1318.0, 1315.0, 1311.0, 1309.0, 1308.0, 1307.0, 1308.0, 1310.0, 1312.0, 1314.0, 1316.0, 1317.0, 1317.0, 1317.0, 1316.0, 1314.0, 1312.0, 1309.0, 1306.0, 1304.0, 1303.0, 1303.0, 1304.0, 1305.0, 1308.0, 1311.0, 1314.0, 1315.0, 1317.0, 1317.0, 1317.0, 1316.0, 1315.0, 1312.0, 1310.0, 1308.0, 1307.0, 1306.0, 1307.0, 1308.0, 1311.0, 1314.0, 1317.0, 1319.0, 1321.0, 1322.0, 1322.0, 1322.0, 1321.0, 1319.0, 1316.0, 1314.0, 1313.0, 1312.0, 1313.0, 1314.0, 1316.0, 1319.0, 1321.0, 1323.0, 1325.0, 1325.0, 1325.0, 1324.0, 1323.0, 1321.0, 1318.0, 1316.0, 1314.0, 1314.0, 1314.0, 1315.0, 1317.0, 1320.0, 1324.0, 1327.0, 1329.0, 1331.0, 1332.0, 1332.0, 1332.0, 1331.0, 1329.0, 1327.0, 1326.0, 1325.0, 1325.0, 1327.0, 1329.0, 1332.0, 1336.0, 1340.0, 1343.0, 1346.0, 1347.0, 1349.0, 1349.0, 1349.0, 1348.0, 1346.0, 1345.0, 1345.0, 1346.0, 1347.0, 1349.0, 1353.0, 1357.0, 1362.0, 1366.0, 1369.0, 1372.0, 1373.0, 1375.0, 1375.0, 1375.0, 1374.0, 1373.0, 1373.0, 1374.0, 1376.0, 1378.0, 1382.0, 1387.0, 1392.0, 1397.0, 1401.0, 1405.0, 1407.0, 1409.0, 1411.0, 1411.0, 1411.0, 1411.0, 1411.0, 1412.0, 1414.0, 1416.0, 1420.0, 1425.0, 1431.0, 1438.0, 1443.0, 1447.0, 1451.0, 1453.0, 1455.0, 1457.0, 1457.0, 1457.0, 1458.0, 1459.0, 1461.0, 1465.0, 1469.0, 1474.0, 1480.0, 1486.0, 1491.0 };
xQ.push_back(xTmp);
yTmp = { 251.0, 261.0, 271.0, 277.0, 284.0, 292.0, 301.0, 311.0, 321.0, 331.0, 341.0, 351.0, 361.0, 371.0, 381.0, 391.0, 401.0, 411.0, 421.0, 431.0, 441.0, 451.0, 461.0, 471.0, 481.0, 491.0, 501.0, 511.0, 521.0, 531.0, 541.0, 551.0, 561.0, 571.0, 581.0, 591.0, 601.0, 611.0, 621.0, 631.0, 641.0, 651.0, 661.0, 671.0, 681.0, 691.0, 701.0, 711.0, 721.0, 731.0, 741.0, 751.0, 761.0, 771.0, 781.0, 791.0, 801.0, 811.0, 821.0, 831.0, 841.0, 851.0, 861.0, 871.0, 881.0, 891.0, 901.0, 911.0, 921.0, 931.0, 941.0, 951.0, 961.0, 971.0, 981.0, 991.0, 1001.0, 1011.0, 1021.0, 1031.0, 1041.0, 1051.0, 1061.0, 1071.0, 1081.0, 1091.0, 1101.0, 1111.0, 1121.0, 1131.0, 1141.0, 1151.0, 1161.0, 1171.0, 1181.0, 1191.0, 1201.0, 1211.0, 1221.0, 1231.0, 1241.0, 1251.0, 1261.0, 1271.0, 1281.0, 1291.0, 1301.0, 1311.0, 1322.0, 1332.0, 1342.0, 1352.0, 1362.0, 1372.0, 1382.0, 1392.0, 1402.0, 1412.0, 1422.0, 1432.0, 1442.0, 1452.0, 1462.0, 1472.0, 1482.0, 1492.0, 1502.0, 1512.0, 1522.0, 1532.0, 1542.0, 1552.0, 1562.0, 1572.0, 1582.0, 1592.0, 1602.0, 1612.0, 1622.0, 1632.0, 1642.0, 1652.0, 1662.0, 1672.0, 1682.0, 1692.0, 1702.0, 1712.0, 1722.0, 1732.0, 1742.0, 1752.0, 1762.0, 1772.0, 1782.0, 1792.0, 1802.0, 1812.0, 1822.0, 1832.0, 1842.0, 1852.0, 1862.0, 1872.0, 1882.0, 1892.0, 1902.0, 1912.0, 1922.0, 1932.0, 1942.0, 1952.0, 1962.0, 1972.0, 1982.0, 1992.0, 2002.0, 2012.0, 2022.0, 2032.0, 2042.0, 2052.0, 2062.0, 2072.0, 2082.0, 2092.0, 2102.0, 2112.0, 2122.0, 2132.0, 2142.0, 2152.0, 2162.0, 2172.0, 2182.0, 2192.0, 2202.0, 2212.0, 2222.0, 2232.0, 2242.0, 2252.0, 2262.0, 2272.0, 2282.0, 2292.0, 2302.0, 2312.0, 2322.0, 2332.0, 2342.0, 2352.0, 2362.0, 2372.0, 2382.0 };
yQ.push_back(yTmp);

xTmp = { 1484.0, 1483.0, 1483.0, 1473.0, 1463.0, 1453.0, 1444.0, 1436.0, 1430.0, 1425.0, 1421.0, 1418.0, 1416.0, 1415.0, 1415.0, 1415.0, 1417.0, 1417.0, 1416.0, 1413.0, 1408.0, 1401.0, 1393.0, 1386.0, 1380.0, 1375.0, 1371.0, 1368.0, 1366.0, 1365.0, 1364.0, 1365.0, 1365.0, 1366.0, 1366.0, 1365.0, 1364.0, 1362.0, 1359.0, 1355.0, 1351.0, 1346.0, 1342.0, 1339.0, 1336.0, 1335.0, 1335.0, 1336.0, 1337.0, 1339.0, 1341.0, 1342.0, 1342.0, 1341.0, 1339.0, 1336.0, 1333.0, 1330.0, 1326.0, 1323.0, 1321.0, 1320.0, 1320.0, 1321.0, 1323.0, 1325.0, 1327.0, 1328.0, 1329.0, 1329.0, 1328.0, 1327.0, 1325.0, 1322.0, 1319.0, 1317.0, 1316.0, 1315.0, 1315.0, 1316.0, 1319.0, 1321.0, 1324.0, 1326.0, 1327.0, 1328.0, 1328.0, 1328.0, 1326.0, 1324.0, 1322.0, 1320.0, 1318.0, 1318.0, 1318.0, 1319.0, 1321.0, 1324.0, 1327.0, 1329.0, 1331.0, 1332.0, 1332.0, 1332.0, 1331.0, 1330.0, 1328.0, 1326.0, 1324.0, 1323.0, 1323.0, 1324.0, 1326.0, 1329.0, 1331.0, 1333.0, 1335.0, 1335.0, 1335.0, 1334.0, 1333.0, 1331.0, 1328.0, 1326.0, 1324.0, 1324.0, 1324.0, 1325.0, 1327.0, 1330.0, 1333.0, 1336.0, 1338.0, 1340.0, 1341.0, 1341.0, 1341.0, 1340.0, 1338.0, 1336.0, 1335.0, 1334.0, 1335.0, 1336.0, 1338.0, 1342.0, 1346.0, 1349.0, 1352.0, 1355.0, 1356.0, 1357.0, 1358.0, 1357.0, 1356.0, 1355.0, 1354.0, 1354.0, 1354.0, 1356.0, 1358.0, 1362.0, 1366.0, 1371.0, 1374.0, 1377.0, 1380.0, 1381.0, 1382.0, 1383.0, 1382.0, 1381.0, 1381.0, 1381.0, 1382.0, 1384.0, 1387.0, 1390.0, 1395.0, 1401.0, 1405.0, 1409.0, 1412.0, 1415.0, 1416.0, 1417.0, 1417.0, 1417.0, 1417.0, 1417.0, 1419.0, 1421.0, 1424.0, 1428.0, 1433.0, 1439.0, 1445.0, 1450.0, 1454.0, 1457.0, 1459.0, 1461.0, 1462.0, 1462.0, 1462.0, 1463.0, 1465.0, 1467.0, 1471.0, 1475.0, 1480.0, 1486.0, 1491.0, 1496.0, 1500.0 };
xQ.push_back(xTmp);
yTmp  = { 254.0, 264.0, 274.0, 280.0, 287.0, 295.0, 305.0, 315.0, 325.0, 335.0, 345.0, 355.0, 365.0, 375.0, 385.0, 395.0, 405.0, 415.0, 425.0, 435.0, 445.0, 455.0, 465.0, 475.0, 485.0, 495.0, 505.0, 515.0, 525.0, 535.0, 545.0, 555.0, 565.0, 575.0, 585.0, 595.0, 605.0, 615.0, 625.0, 635.0, 645.0, 655.0, 665.0, 675.0, 685.0, 695.0, 705.0, 715.0, 725.0, 735.0, 745.0, 755.0, 765.0, 775.0, 785.0, 795.0, 805.0, 815.0, 825.0, 835.0, 845.0, 855.0, 865.0, 875.0, 885.0, 895.0, 905.0, 915.0, 925.0, 935.0, 945.0, 955.0, 965.0, 975.0, 985.0, 995.0, 1005.0, 1015.0, 1025.0, 1035.0, 1045.0, 1055.0, 1065.0, 1075.0, 1085.0, 1095.0, 1105.0, 1115.0, 1125.0, 1135.0, 1145.0, 1155.0, 1165.0, 1175.0, 1185.0, 1195.0, 1205.0, 1215.0, 1225.0, 1235.0, 1245.0, 1255.0, 1265.0, 1275.0, 1285.0, 1295.0, 1305.0, 1315.0, 1326.0, 1336.0, 1346.0, 1356.0, 1366.0, 1376.0, 1386.0, 1396.0, 1406.0, 1416.0, 1426.0, 1436.0, 1446.0, 1456.0, 1466.0, 1476.0, 1486.0, 1496.0, 1506.0, 1516.0, 1526.0, 1536.0, 1546.0, 1556.0, 1566.0, 1576.0, 1586.0, 1596.0, 1606.0, 1616.0, 1626.0, 1636.0, 1646.0, 1656.0, 1666.0, 1676.0, 1686.0, 1696.0, 1706.0, 1716.0, 1726.0, 1736.0, 1746.0, 1756.0, 1766.0, 1776.0, 1786.0, 1796.0, 1806.0, 1816.0, 1826.0, 1836.0, 1846.0, 1856.0, 1866.0, 1876.0, 1886.0, 1896.0, 1906.0, 1916.0, 1926.0, 1936.0, 1946.0, 1956.0, 1966.0, 1976.0, 1986.0, 1996.0, 2006.0, 2016.0, 2026.0, 2036.0, 2046.0, 2056.0, 2066.0, 2076.0, 2086.0, 2096.0, 2106.0, 2116.0, 2126.0, 2136.0, 2146.0, 2156.0, 2166.0, 2176.0, 2186.0, 2196.0, 2206.0, 2216.0, 2226.0, 2236.0, 2246.0, 2256.0, 2266.0, 2276.0, 2286.0, 2296.0, 2306.0, 2316.0, 2326.0, 2336.0, 2346.0, 2356.0, 2366.0, 2376.0, 2386.0 };
yQ.push_back(yTmp);

// Bad Contour: high Score
xTmp = { 1468.0, 1465.0, 1465.0, 1467.0, 1458.0, 1449.0, 1442.0, 1434.0, 1428.0, 1423.0, 1419.0, 1416.0, 1415.0, 1414.0, 1414.0, 1415.0, 1416.0, 1419.0, 1421.0, 1423.0, 1423.0, 1421.0, 1417.0, 1412.0, 1406.0, 1401.0, 1397.0, 1395.0, 1393.0, 1393.0, 1395.0, 1398.0, 1402.0, 1407.0, 1414.0, 1422.0, 1428.0, 1434.0, 1437.0, 1434.0, 1430.0, 1427.0, 1430.0, 1432.0, 1433.0, 1434.0, 1435.0, 1435.0, 1436.0, 1438.0, 1440.0, 1442.0, 1442.0, 1442.0, 1440.0, 1438.0, 1436.0, 1432.0, 1428.0, 1423.0, 1419.0, 1415.0, 1413.0, 1411.0, 1411.0, 1411.0, 1411.0, 1412.0, 1413.0, 1412.0, 1412.0, 1411.0, 1409.0, 1405.0, 1401.0, 1395.0, 1389.0, 1383.0, 1379.0, 1375.0, 1370.0, 1367.0, 1365.0, 1364.0, 1364.0, 1364.0, 1364.0, 1363.0, 1361.0, 1359.0, 1356.0, 1353.0, 1348.0, 1344.0, 1341.0, 1338.0, 1336.0, 1335.0, 1335.0, 1337.0, 1339.0, 1341.0, 1343.0, 1345.0, 1345.0, 1345.0, 1345.0, 1344.0, 1342.0, 1339.0, 1337.0, 1335.0, 1333.0, 1333.0, 1333.0, 1334.0, 1336.0, 1338.0, 1339.0, 1341.0, 1341.0, 1341.0, 1340.0, 1339.0, 1337.0, 1334.0, 1331.0, 1329.0, 1327.0, 1327.0, 1327.0, 1328.0, 1330.0, 1333.0, 1336.0, 1338.0, 1340.0, 1341.0, 1342.0, 1341.0, 1340.0, 1339.0, 1337.0, 1335.0, 1334.0, 1333.0, 1334.0, 1335.0, 1338.0, 1341.0, 1345.0, 1348.0, 1351.0, 1353.0, 1354.0, 1355.0, 1355.0, 1354.0, 1353.0, 1351.0, 1350.0, 1350.0, 1351.0, 1353.0, 1355.0, 1359.0, 1363.0, 1367.0, 1371.0, 1374.0, 1376.0, 1377.0, 1378.0, 1378.0, 1378.0, 1377.0, 1376.0, 1376.0, 1377.0, 1379.0, 1382.0, 1385.0, 1390.0, 1396.0, 1400.0, 1404.0, 1407.0, 1409.0, 1411.0, 1412.0, 1412.0, 1412.0, 1411.0, 1412.0, 1413.0, 1415.0, 1418.0, 1422.0, 1426.0, 1432.0, 1438.0, 1443.0, 1447.0, 1451.0, 1453.0, 1455.0, 1456.0, 1456.0, 1456.0, 1457.0, 1458.0, 1461.0, 1464.0, 1468.0, 1473.0, 1479.0, 1484.0, 1489.0 };
xQ.push_back(xTmp);
yTmp = { 259.0, 269.0, 279.0, 289.0, 297.0, 304.0, 312.0, 322.0, 332.0, 342.0, 352.0, 362.0, 372.0, 382.0, 392.0, 402.0, 412.0, 422.0, 432.0, 442.0, 452.0, 462.0, 472.0, 482.0, 492.0, 502.0, 512.0, 522.0, 532.0, 542.0, 552.0, 562.0, 572.0, 582.0, 592.0, 602.0, 612.0, 622.0, 632.0, 637.0, 631.0, 633.0, 643.0, 653.0, 663.0, 673.0, 683.0, 693.0, 703.0, 713.0, 723.0, 733.0, 743.0, 753.0, 763.0, 773.0, 783.0, 793.0, 803.0, 813.0, 823.0, 833.0, 843.0, 853.0, 863.0, 873.0, 883.0, 893.0, 903.0, 913.0, 923.0, 933.0, 943.0, 953.0, 963.0, 973.0, 983.0, 993.0, 1002.0, 1004.0, 1011.0, 1021.0, 1031.0, 1041.0, 1051.0, 1061.0, 1071.0, 1081.0, 1091.0, 1101.0, 1111.0, 1121.0, 1131.0, 1141.0, 1151.0, 1161.0, 1171.0, 1181.0, 1191.0, 1201.0, 1211.0, 1221.0, 1231.0, 1241.0, 1251.0, 1261.0, 1271.0, 1281.0, 1291.0, 1301.0, 1311.0, 1321.0, 1332.0, 1342.0, 1352.0, 1362.0, 1372.0, 1382.0, 1392.0, 1402.0, 1412.0, 1422.0, 1432.0, 1442.0, 1452.0, 1462.0, 1472.0, 1482.0, 1492.0, 1502.0, 1512.0, 1522.0, 1532.0, 1542.0, 1552.0, 1562.0, 1572.0, 1582.0, 1592.0, 1602.0, 1612.0, 1622.0, 1632.0, 1642.0, 1652.0, 1662.0, 1672.0, 1682.0, 1692.0, 1702.0, 1712.0, 1722.0, 1732.0, 1742.0, 1752.0, 1762.0, 1772.0, 1782.0, 1792.0, 1802.0, 1812.0, 1822.0, 1832.0, 1842.0, 1852.0, 1862.0, 1872.0, 1882.0, 1892.0, 1902.0, 1912.0, 1922.0, 1932.0, 1942.0, 1952.0, 1962.0, 1972.0, 1982.0, 1992.0, 2002.0, 2012.0, 2022.0, 2032.0, 2042.0, 2052.0, 2062.0, 2072.0, 2082.0, 2092.0, 2102.0, 2112.0, 2122.0, 2132.0, 2142.0, 2152.0, 2162.0, 2172.0, 2182.0, 2192.0, 2202.0, 2212.0, 2222.0, 2232.0, 2242.0, 2252.0, 2262.0, 2272.0, 2282.0, 2292.0, 2302.0, 2312.0, 2322.0, 2332.0, 2342.0, 2352.0, 2362.0, 2372.0, 2382.0 };
yQ.push_back(yTmp);

// Bad Contour: Low Score
xTmp = { 1607.0, 1603.0, 1602.0, 1604.0, 1603.0, 1596.0, 1588.0, 1580.0, 1575.0, 1571.0, 1568.0, 1566.0, 1565.0, 1565.0, 1566.0, 1566.0, 1566.0, 1568.0, 1569.0, 1571.0, 1572.0, 1573.0, 1573.0, 1572.0, 1572.0, 1571.0, 1569.0, 1568.0, 1566.0, 1563.0, 1561.0, 1558.0, 1555.0, 1552.0, 1549.0, 1545.0, 1542.0, 1539.0, 1534.0, 1528.0, 1520.0, 1512.0, 1506.0, 1501.0, 1497.0, 1494.0, 1488.0, 1482.0, 1478.0, 1477.0, 1477.0, 1477.0, 1478.0, 1478.0, 1477.0, 1476.0, 1475.0, 1473.0, 1478.0, 1480.0, 1482.0, 1483.0, 1484.0, 1484.0, 1483.0, 1483.0, 1484.0, 1486.0, 1489.0, 1489.0, 1489.0, 1490.0, 1490.0, 1489.0, 1489.0, 1487.0, 1484.0, 1481.0, 1479.0, 1474.0, 1470.0, 1467.0, 1466.0, 1465.0, 1465.0, 1466.0, 1467.0, 1470.0, 1472.0, 1474.0, 1475.0, 1475.0, 1475.0, 1474.0, 1472.0, 1470.0, 1467.0, 1464.0, 1462.0, 1461.0, 1461.0, 1461.0, 1464.0, 1467.0, 1470.0, 1473.0, 1475.0, 1476.0, 1477.0, 1476.0, 1476.0, 1475.0, 1473.0, 1471.0, 1468.0, 1467.0, 1467.0, 1468.0, 1469.0, 1472.0, 1475.0, 1479.0, 1482.0, 1485.0, 1488.0, 1489.0, 1489.0, 1488.0, 1487.0, 1486.0, 1484.0, 1483.0, 1483.0, 1484.0, 1486.0, 1489.0, 1493.0, 1497.0, 1491.0, 1491.0, 1494.0, 1496.0, 1499.0, 1501.0, 1502.0, 1502.0, 1495.0, 1490.0, 1487.0, 1484.0, 1482.0, 1483.0, 1488.0, 1487.0, 1486.0, 1488.0, 1492.0, 1498.0, 1502.0, 1499.0, 1497.0, 1493.0, 1492.0, 1489.0, 1492.0, 1494.0, 1497.0, 1499.0, 1499.0, 1502.0, 1501.0, 1503.0, 1501.0, 1503.0, 1499.0, 1496.0, 1496.0, 1494.0, 1492.0, 1491.0, 1486.0, 1485.0, 1486.0, 1488.0, 1492.0, 1498.0, 1503.0, 1509.0, 1512.0, 1514.0, 1515.0, 1516.0, 1517.0, 1516.0, 1515.0, 1514.0, 1512.0, 1511.0, 1511.0, 1512.0, 1514.0, 1517.0, 1520.0, 1525.0, 1529.0, 1533.0, 1536.0, 1538.0, 1540.0, 1541.0, 1541.0, 1540.0, 1539.0, 1539.0, 1538.0, 1539.0, 1541.0, 1544.0, 1548.0, 1552.0, 1558.0, 1562.0, 1566.0, 1570.0, 1572.0, 1574.0, 1575.0, 1575.0, 1575.0, 1575.0, 1575.0, 1576.0, 1578.0, 1580.0, 1584.0, 1588.0, 1594.0, 1600.0, 1605.0, 1610.0, 1613.0, 1616.0, 1618.0, 1620.0, 1621.0, 1621.0, 1621.0, 1622.0, 1624.0, 1627.0, 1630.0, 1635.0, 1640.0 };
xQ.push_back(xTmp);
yTmp = { 246.0, 256.0, 266.0, 276.0, 286.0, 293.0, 301.0, 311.0, 321.0, 331.0, 341.0, 351.0, 361.0, 371.0, 381.0, 391.0, 401.0, 411.0, 421.0, 431.0, 441.0, 451.0, 461.0, 471.0, 481.0, 491.0, 501.0, 511.0, 521.0, 531.0, 541.0, 551.0, 561.0, 571.0, 581.0, 591.0, 601.0, 611.0, 621.0, 631.0, 641.0, 651.0, 661.0, 671.0, 681.0, 691.0, 701.0, 711.0, 721.0, 731.0, 741.0, 751.0, 761.0, 771.0, 781.0, 791.0, 801.0, 811.0, 810.0, 800.0, 790.0, 780.0, 770.0, 760.0, 750.0, 740.0, 730.0, 720.0, 725.0, 735.0, 745.0, 755.0, 765.0, 775.0, 785.0, 795.0, 805.0, 815.0, 825.0, 835.0, 845.0, 855.0, 865.0, 875.0, 885.0, 895.0, 905.0, 915.0, 925.0, 935.0, 945.0, 955.0, 965.0, 975.0, 985.0, 995.0, 1005.0, 1015.0, 1025.0, 1035.0, 1045.0, 1055.0, 1065.0, 1075.0, 1085.0, 1095.0, 1105.0, 1115.0, 1125.0, 1135.0, 1145.0, 1155.0, 1165.0, 1175.0, 1185.0, 1195.0, 1205.0, 1215.0, 1225.0, 1235.0, 1245.0, 1255.0, 1265.0, 1275.0, 1285.0, 1295.0, 1305.0, 1316.0, 1326.0, 1336.0, 1346.0, 1356.0, 1366.0, 1376.0, 1386.0, 1396.0, 1406.0, 1416.0, 1406.0, 1414.0, 1424.0, 1434.0, 1444.0, 1454.0, 1464.0, 1472.0, 1479.0, 1489.0, 1499.0, 1509.0, 1519.0, 1529.0, 1537.0, 1527.0, 1517.0, 1507.0, 1497.0, 1487.0, 1481.0, 1491.0, 1501.0, 1511.0, 1520.0, 1526.0, 1536.0, 1545.0, 1555.0, 1565.0, 1575.0, 1583.0, 1592.0, 1600.0, 1606.0, 1610.0, 1609.0, 1617.0, 1627.0, 1637.0, 1647.0, 1651.0, 1660.0, 1670.0, 1680.0, 1690.0, 1700.0, 1709.0, 1718.0, 1724.0, 1734.0, 1744.0, 1754.0, 1764.0, 1774.0, 1784.0, 1794.0, 1804.0, 1814.0, 1824.0, 1834.0, 1844.0, 1854.0, 1864.0, 1874.0, 1884.0, 1894.0, 1904.0, 1914.0, 1924.0, 1934.0, 1944.0, 1954.0, 1964.0, 1974.0, 1984.0, 1994.0, 2004.0, 2014.0, 2024.0, 2034.0, 2044.0, 2054.0, 2064.0, 2074.0, 2084.0, 2094.0, 2104.0, 2114.0, 2124.0, 2134.0, 2144.0, 2154.0, 2164.0, 2174.0, 2184.0, 2194.0, 2204.0, 2214.0, 2224.0, 2234.0, 2244.0, 2254.0, 2264.0, 2274.0, 2284.0, 2294.0, 2304.0, 2314.0, 2324.0, 2334.0, 2344.0, 2354.0, 2364.0, 2374.0 };
yQ.push_back(yTmp);

// Template Contour
vector<Point> templateContour = toCVContour(xPtsT, yPtsT);
Mat templateImg = Mat::zeros(Size(4000, 3000), CV_64FC1);
drawContourPts(templateImg, templateContour);
resize(templateImg, templateImg, Size(templateImg.cols / 3, templateImg.rows / 3));
imshow("Template", templateImg);

for (int q = 0; q < xQ.size(); q++)
{
    vector<double> xQuery = xQ[q];
    vector<double> yQuery = yQ[q];

    vector<Point> queryContour = toCVContour(xQuery, yQuery);
    Mat queryImg = Mat::zeros(Size(4000, 3000), CV_64FC1);
    drawContourPts(queryImg, queryContour);
    resize(queryImg, queryImg, Size(queryImg.cols / 3, queryImg.rows / 3));

    //Match Shapes
    double score = matchShapes(templateContour, queryContour, CONTOURS_MATCH_I2, 0);

    // Print Score
    cv::putText(queryImg,
        std::to_string(score),
        cv::Point(50, 180), 
        cv::FONT_HERSHEY_COMPLEX_SMALL, 
        3.0, 
        cv::Scalar(255, 255, 255),
        1, // 
        LINE_8, false); 
    imshow("Query with Score", queryImg);
    waitKey();
    string filename = "Res" + to_string(q) + ".jpg";
    //imwrite(filename, queryImg);
}


return 0;
}

As the result images show, this works relatively well for some errors, unfortunately there are also cases where errors have a low score. I could imagine that this is due to the following reasons:

  1. the contours are shifted translationally and do not always start at the same point, maybe this has to be compensated
  2. Judging by moments is not the right tool
  3. The contours are not closed

I would be grateful for your comments or suggestions for an alternative approach.

Good Part with Low Score:

image description

Good Part with Low Score:

image description

Bad Part with High Score

image description

Bad Part with Low Score image description