Advertisement
Guest User

Proiect PI

a guest
May 24th, 2019
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 77.66 KB | None | 0 0
  1. // OpenCVApplication.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "common.h"
  6. #include <random>
  7. #include <filesystem>
  8.  
  9. using namespace std;
  10.  
  11. void testOpenImage()
  12. {
  13. char fname[MAX_PATH];
  14. while(openFileDlg(fname))
  15. {
  16. Mat src;
  17. src = imread(fname);
  18. imshow("image",src);
  19. waitKey();
  20.  
  21. }
  22. }
  23.  
  24. void testOpenImagesFld()
  25. {
  26. char folderName[MAX_PATH];
  27. if (openFolderDlg(folderName)==0)
  28. return;
  29. char fname[MAX_PATH];
  30. FileGetter fg(folderName,"bmp");
  31. while(fg.getNextAbsFile(fname))
  32. {
  33. Mat src;
  34. src = imread(fname);
  35. imshow(fg.getFoundFileName(),src);
  36. if (waitKey()==27) //ESC pressed
  37. break;
  38. }
  39. }
  40.  
  41. void testImageOpenAndSave()
  42. {
  43. Mat src, dst;
  44.  
  45. src = imread("Images/Lena_24bits.bmp", CV_LOAD_IMAGE_COLOR); // Read the image
  46.  
  47. if (!src.data) // Check for invalid input
  48. {
  49. printf("Could not open or find the image\n");
  50. return;
  51. }
  52.  
  53. // Get the image resolution
  54. Size src_size = Size(src.cols, src.rows);
  55.  
  56. // Display window
  57. const char* WIN_SRC = "Src"; //window for the source image
  58. namedWindow(WIN_SRC, CV_WINDOW_AUTOSIZE);
  59. cvMoveWindow(WIN_SRC, 0, 0);
  60.  
  61. const char* WIN_DST = "Dst"; //window for the destination (processed) image
  62. namedWindow(WIN_DST, CV_WINDOW_AUTOSIZE);
  63. cvMoveWindow(WIN_DST, src_size.width + 10, 0);
  64.  
  65. cvtColor(src, dst, CV_BGR2GRAY); //converts the source image to a grayscale one
  66.  
  67. imwrite("Images/Lena_24bits_gray.bmp", dst); //writes the destination to file
  68.  
  69. imshow(WIN_SRC, src);
  70. imshow(WIN_DST, dst);
  71.  
  72. printf("Press any key to continue ...\n");
  73. waitKey(0);
  74. }
  75.  
  76. void negative_image() {
  77. Mat img = imread("Images/cameraman.bmp",
  78. CV_LOAD_IMAGE_GRAYSCALE);
  79.  
  80. for (int i = 0; i<img.rows; i++) {
  81. for (int j = 0; j<img.cols; j++) {
  82. img.at<uchar>(i, j) = 255 - img.at<uchar>(i, j);
  83. }
  84. }
  85. imshow("negative image", img);
  86. waitKey(0);
  87. }
  88.  
  89. void testNegativeImage()
  90. {
  91. char fname[MAX_PATH];
  92. while(openFileDlg(fname))
  93. {
  94. double t = (double)getTickCount(); // Get the current time [s]
  95.  
  96. Mat src = imread(fname,CV_LOAD_IMAGE_GRAYSCALE);
  97. int height = src.rows;
  98. int width = src.cols;
  99. Mat dst = Mat(height,width,CV_8UC1);
  100. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  101. // Varianta ineficienta (lenta)
  102. for (int i=0; i<height; i++)
  103. {
  104. for (int j=0; j<width; j++)
  105. {
  106. uchar val = src.at<uchar>(i,j);
  107. uchar neg = 255 - val;
  108. dst.at<uchar>(i,j) = neg;
  109. }
  110. }
  111.  
  112. // Get the current time again and compute the time difference [s]
  113. t = ((double)getTickCount() - t) / getTickFrequency();
  114. // Print (in the console window) the processing time in [ms]
  115. printf("Time = %.3f [ms]\n", t * 1000);
  116.  
  117. imshow("input image",src);
  118. imshow("negative image",dst);
  119. waitKey();
  120. }
  121. }
  122.  
  123. void testNegativeImageP()
  124. {
  125. char fname[MAX_PATH];
  126. while (openFileDlg(fname))
  127. {
  128. double t = (double)getTickCount(); // Get the current time [s]
  129.  
  130. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  131. int height = src.rows;
  132. int width = src.cols;
  133. Mat dst = Mat(height, width, CV_8UC1);
  134. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  135. // Varianta ineficienta (lenta)
  136. for (int i = 0; i<height; i++)
  137. {
  138. for (int j = 0; j<width; j++)
  139. {
  140. uchar val = src.at<uchar>(i, j);
  141. int neg = val + 255;
  142. neg = neg > 255 ? 255 : neg;
  143. neg = neg < 0 ? 0 : neg;
  144. dst.at<uchar>(i, j) = neg;
  145. }
  146. }
  147.  
  148. // Get the current time again and compute the time difference [s]
  149. t = ((double)getTickCount() - t) / getTickFrequency();
  150. // Print (in the console window) the processing time in [ms]
  151. printf("Time = %.3f [ms]\n", t * 1000);
  152.  
  153. imshow("input image", src);
  154. imshow("added gray image", dst);
  155.  
  156. waitKey();
  157. destroyAllWindows();
  158.  
  159. }
  160. }
  161.  
  162. void testNegativeImageM()
  163. {
  164. char fname[MAX_PATH];
  165. while (openFileDlg(fname))
  166. {
  167. double t = (double)getTickCount(); // Get the current time [s]
  168.  
  169. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  170. int height = src.rows;
  171. int width = src.cols;
  172. Mat dst = Mat(height, width, CV_8UC1);
  173. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  174. // Varianta ineficienta (lenta)
  175. for (int i = 0; i<height; i++)
  176. {
  177. for (int j = 0; j<width; j++)
  178. {
  179. uchar val = src.at<uchar>(i, j);
  180. int neg = (int)(val*1.50);
  181. neg = neg > 255 ? 255 : neg;
  182. neg = neg < 0 ? 0 : neg;
  183. dst.at<uchar>(i, j) = (uchar)neg;
  184. }
  185. }
  186.  
  187. // Get the current time again and compute the time difference [s]
  188. t = ((double)getTickCount() - t) / getTickFrequency();
  189. // Print (in the console window) the processing time in [ms]
  190. printf("Time = %.3f [ms]\n", t * 1000);
  191.  
  192. imshow("input image", src);
  193. imshow("multiplied gray image", dst);
  194. imwrite("D:\\Projects\\Lab\\PI\\OpenCVApplication-VS2017_OCV340_basic\\Images\\imagine_salvata.bmp", dst);
  195. waitKey();
  196. destroyAllWindows();
  197. }
  198. }
  199.  
  200.  
  201. void test4Flag()
  202. {
  203. Vec3b alb = Vec3b(255, 255, 255);//bgr
  204. Vec3b rosu = Vec3b(0, 0, 255);
  205. Vec3b verde = Vec3b(0, 255, 0);
  206. Vec3b galben = Vec3b(0, 255, 255);
  207. char fname[MAX_PATH];
  208. //while (openFileDlg(fname))
  209. {
  210. double t = (double)getTickCount(); // Get the current time [s]
  211.  
  212. int height = 256;
  213. int width = 256;
  214. Mat dst = Mat(height, width, CV_8UC3);
  215. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  216. // Varianta ineficienta (lenta)
  217. for (int i = 0; i<height; i++)
  218. {
  219. for (int j = 0; j<width; j++)
  220. {
  221. if (i < 128 && j < 128)
  222. dst.at<Vec3b>(i, j) = alb;
  223. else if (i > 128 && j < 128)
  224. dst.at<Vec3b>(i, j) = rosu;
  225. else if (i < 128 && j > 128)
  226. dst.at<Vec3b>(i, j) = verde;
  227. else
  228. dst.at<Vec3b>(i, j) = galben;
  229.  
  230.  
  231. }
  232. }
  233.  
  234. // Get the current time again and compute the time difference [s]
  235. t = ((double)getTickCount() - t) / getTickFrequency();
  236. // Print (in the console window) the processing time in [ms]
  237. printf("Time = %.3f [ms]\n", t * 1000);
  238.  
  239. imshow("flag", dst);
  240. waitKey();
  241. destroyAllWindows();
  242. }
  243. }
  244.  
  245. void testInvMat3f()
  246. {
  247. int height = 3;
  248. int width = 3;
  249.  
  250. float vals[9] = { 3, 0, 0, 0, 3, 0, 0, 0, 3 };
  251. Mat dst = Mat(width, height, CV_32FC1, vals);
  252.  
  253. cout << "Input image:\n";
  254.  
  255. for (int i = 0; i < height; i++)
  256. {
  257. for (int j = 0; j < width; j++)
  258. {
  259. //dst.at<float>(i, j) = 0.7f;
  260. cout << dst.at<float>(i, j) << " ";
  261. }
  262. cout << endl;
  263. }
  264.  
  265. cout << endl;
  266.  
  267. dst= dst.inv();
  268.  
  269. for (int i = 0; i < height; i++)
  270. {
  271. for (int j = 0; j < width; j++)
  272. {
  273. cout << dst.at<float>(i, j) << " ";
  274. }
  275. cout << endl;
  276.  
  277. }
  278.  
  279. system("pause >nul");
  280. }
  281.  
  282.  
  283.  
  284. void testParcurgereSimplaDiblookStyle()
  285. {
  286. char fname[MAX_PATH];
  287. while (openFileDlg(fname))
  288. {
  289. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  290. int height = src.rows;
  291. int width = src.cols;
  292. Mat dst = src.clone();
  293.  
  294. double t = (double)getTickCount(); // Get the current time [s]
  295.  
  296. // the fastest approach using the �diblook style�
  297. uchar *lpSrc = src.data;
  298. uchar *lpDst = dst.data;
  299. int w = (int) src.step; // no dword alignment is done !!!
  300. for (int i = 0; i<height; i++)
  301. for (int j = 0; j < width; j++) {
  302. uchar val = lpSrc[i*w + j];
  303. lpDst[i*w + j] = 255 - val;
  304. }
  305.  
  306. // Get the current time again and compute the time difference [s]
  307. t = ((double)getTickCount() - t) / getTickFrequency();
  308. // Print (in the console window) the processing time in [ms]
  309. printf("Time = %.3f [ms]\n", t * 1000);
  310.  
  311. imshow("input image",src);
  312. imshow("negative image",dst);
  313. waitKey();
  314. }
  315. }
  316.  
  317. void testColor2Gray()
  318. {
  319. char fname[MAX_PATH];
  320. while(openFileDlg(fname))
  321. {
  322. Mat src = imread(fname);
  323.  
  324. int height = src.rows;
  325. int width = src.cols;
  326.  
  327. Mat dst = Mat(height,width,CV_8UC1);
  328.  
  329. // Asa se acceseaaza pixelii individuali pt. o imagine RGB 24 biti/pixel
  330. // Varianta ineficienta (lenta)
  331. for (int i=0; i<height; i++)
  332. {
  333. for (int j=0; j<width; j++)
  334. {
  335. Vec3b v3 = src.at<Vec3b>(i,j);
  336. uchar b = v3[0];
  337. uchar g = v3[1];
  338. uchar r = v3[2];
  339. dst.at<uchar>(i,j) = (r+g+b)/3;
  340. }
  341. }
  342.  
  343. imshow("input image",src);
  344. imshow("gray image",dst);
  345. waitKey();
  346. }
  347. }
  348.  
  349. void testRGBComp()
  350. {
  351. char fname[MAX_PATH];
  352. while (openFileDlg(fname))
  353. {
  354. double t = (double)getTickCount(); // Get the current time [s]
  355.  
  356. Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
  357. int height = src.rows;
  358. int width = src.cols;
  359.  
  360. Mat dstr = Mat(height, width, CV_8UC1);
  361. Mat dstg = Mat(height, width, CV_8UC1);
  362. Mat dstb = Mat(height, width, CV_8UC1);
  363.  
  364. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  365. // Varianta ineficienta (lenta)
  366. for (int i = 0; i<height; i++)
  367. {
  368. for (int j = 0; j<width; j++)
  369. {
  370. Vec3b val = src.at<Vec3b>(i, j);
  371.  
  372. dstr.at<uchar>(i, j) = val[2];
  373. dstg.at<uchar>(i, j) = val[1];
  374. dstb.at<uchar>(i, j) = val[0];
  375. }
  376. }
  377.  
  378. // Get the current time again and compute the time difference [s]
  379. t = ((double)getTickCount() - t) / getTickFrequency();
  380. // Print (in the console window) the processing time in [ms]
  381. printf("Time = %.3f [ms]\n", t * 1000);
  382.  
  383. imshow("input image", src);
  384. imshow("b image", dstr);
  385. imshow("g image", dstg);
  386. imshow("r image", dstb);
  387. waitKey();
  388. destroyAllWindows();
  389.  
  390. }
  391. }
  392.  
  393. float maxf(float a, float b, float c)
  394. {
  395. if (a > b)
  396. if (a > c)
  397. return a;
  398. else
  399. return c;
  400. else
  401. if (b > c)
  402. return b;
  403. else
  404. return c;
  405. }
  406.  
  407. float minf(float a, float b, float c)
  408. {
  409. if (a < b)
  410. if (a < c)
  411. return a;
  412. else
  413. return c;
  414. else
  415. if (b < c)
  416. return b;
  417. else
  418. return c;
  419. }
  420.  
  421. void testRGBHSV()
  422. {
  423. char fname[MAX_PATH];
  424. while (openFileDlg(fname))
  425. {
  426. double t = (double)getTickCount(); // Get the current time [s]
  427.  
  428. Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
  429. int height = src.rows;
  430. int width = src.cols;
  431.  
  432. Mat dstr = Mat(height, width, CV_8UC1);
  433. Mat dstg = Mat(height, width, CV_8UC1);
  434. Mat dstb = Mat(height, width, CV_8UC1);
  435.  
  436. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  437. // Varianta ineficienta (lenta)
  438. for (int i = 0; i<height; i++)
  439. {
  440. for (int j = 0; j<width; j++)
  441. {
  442. Vec3b val = src.at<Vec3b>(i, j);
  443.  
  444. float r = val[2] / 255.0f;
  445. float g = val[1] / 255.0f;
  446. float b = val[0] / 255.0f;
  447.  
  448.  
  449. float ma = maxf(r, g, b);
  450. float mi = minf(r, g, b);
  451. float C = ma - mi;
  452.  
  453. float V = ma;
  454.  
  455. float S = 0.0;
  456. if (V > 0.0001f)
  457. S = C / V;
  458.  
  459. float H = 0.0f;
  460. if(C > 0.001)
  461. {
  462. if (ma - r < 0.001f) H = 60 * (g - b) / C;
  463. if (ma - g < 0.001f) H = 120 * (b - r) / C;
  464. if (ma - b < 0.001f) H = 240 * (r - g) / C;
  465. }
  466.  
  467. if (H < 0.0f)
  468. H += 360.0f;
  469.  
  470. dstr.at<uchar>(i, j) = (uchar)(H * 255 / 360);
  471. dstg.at<uchar>(i, j) = (uchar)(S * 255);
  472. dstb.at<uchar>(i, j) = (uchar)(V * 255);
  473. }
  474. }
  475.  
  476. // Get the current time again and compute the time difference [s]
  477. t = ((double)getTickCount() - t) / getTickFrequency();
  478. // Print (in the console window) the processing time in [ms]
  479. printf("Time = %.3f [ms]\n", t * 1000);
  480.  
  481. imshow("input image", src);
  482. imshow("h image", dstr);
  483. imshow("s image", dstg);
  484. imshow("v image", dstb);
  485. waitKey();
  486. destroyAllWindows();
  487.  
  488. }
  489. }
  490.  
  491. void testBGR2HSV()
  492. {
  493. char fname[MAX_PATH];
  494. while (openFileDlg(fname))
  495. {
  496. Mat src = imread(fname);
  497. int height = src.rows;
  498. int width = src.cols;
  499.  
  500. // Componentele d eculoare ale modelului HSV
  501. Mat H = Mat(height, width, CV_8UC1);
  502. Mat S = Mat(height, width, CV_8UC1);
  503. Mat V = Mat(height, width, CV_8UC1);
  504.  
  505. // definire pointeri la matricele (8 biti/pixeli) folosite la afisarea componentelor individuale H,S,V
  506. uchar* lpH = H.data;
  507. uchar* lpS = S.data;
  508. uchar* lpV = V.data;
  509.  
  510. Mat hsvImg;
  511. cvtColor(src, hsvImg, CV_BGR2HSV);
  512.  
  513. // definire pointer la matricea (24 biti/pixeli) a imaginii HSV
  514. uchar* hsvDataPtr = hsvImg.data;
  515.  
  516. for (int i = 0; i<height; i++)
  517. {
  518. for (int j = 0; j<width; j++)
  519. {
  520. int hi = i*width * 3 + j * 3;
  521. int gi = i*width + j;
  522.  
  523. lpH[gi] = hsvDataPtr[hi] * 510 / 360; // lpH = 0 .. 255
  524. lpS[gi] = hsvDataPtr[hi + 1]; // lpS = 0 .. 255
  525. lpV[gi] = hsvDataPtr[hi + 2]; // lpV = 0 .. 255
  526. }
  527. }
  528.  
  529. imshow("input image", src);
  530. imshow("H", H);
  531. imshow("S", S);
  532. imshow("V", V);
  533.  
  534. waitKey();
  535. }
  536. }
  537.  
  538. void testThreshold()
  539. {
  540. char fname[MAX_PATH];
  541. cout << "Da un numar bun: ";
  542. int thres;
  543. cin >> thres;
  544. thres = thres > 255 ? 255 : thres;
  545. thres = thres < 0 ? 0 : thres;
  546.  
  547. while (openFileDlg(fname))
  548. {
  549. double t = (double)getTickCount(); // Get the current time [s]
  550.  
  551. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  552. int height = src.rows;
  553. int width = src.cols;
  554. Mat dst = Mat(height, width, CV_8UC1);
  555. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  556. // Varianta ineficienta (lenta)
  557. for (int i = 0; i<height; i++)
  558. {
  559. for (int j = 0; j<width; j++)
  560. {
  561. uchar val = src.at<uchar>(i, j);
  562. if(val > thres)
  563. dst.at<uchar>(i, j) = (uchar)255;
  564. if(val < thres)
  565. dst.at<uchar>(i, j) = (uchar)0;
  566. }
  567. }
  568.  
  569. // Get the current time again and compute the time difference [s]
  570. t = ((double)getTickCount() - t) / getTickFrequency();
  571. // Print (in the console window) the processing time in [ms]
  572. printf("Time = %.3f [ms]\n", t * 1000);
  573.  
  574. imshow("input image", src);
  575. imshow("multiplied gray image", dst);
  576. waitKey();
  577. destroyAllWindows();
  578. }
  579. }
  580.  
  581. bool isInside(Mat m, int i, int j)
  582. {
  583. return i >= 0 && j >= 0 && j < m.cols && i < m.rows;
  584. }
  585.  
  586. void testIsInside()
  587. {
  588. char fname[MAX_PATH];
  589.  
  590. cout << "Dati numere consecutive i,j sau -1000 pentru stop\n";
  591.  
  592. if (openFileDlg(fname))
  593. {
  594. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  595. int i, j;
  596. while (true)
  597. {
  598. cin >> i;
  599. if (i == -1000)
  600. return;
  601. cin >> j;
  602. if (j == -1000)
  603. return;
  604. cout << isInside(src, i, j) << endl;
  605. }
  606. }
  607. }
  608.  
  609. void testRGBGray()
  610. {
  611. char fname[MAX_PATH];
  612.  
  613. while (openFileDlg(fname))
  614. {
  615. double t = (double)getTickCount(); // Get the current time [s]
  616.  
  617. Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
  618. int height = src.rows;
  619. int width = src.cols;
  620. Mat dst = Mat(height, width, CV_8UC1);
  621. // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
  622. // Varianta ineficienta (lenta)
  623. for (int i = 0; i<height; i++)
  624. {
  625. for (int j = 0; j<width; j++)
  626. {
  627.  
  628. uchar r = src.at<Vec3b>(i, j)[2];
  629. uchar g = src.at<Vec3b>(i, j)[1];
  630. uchar b = src.at<Vec3b>(i, j)[0];
  631. dst.at<uchar>(i, j) = (uchar)((r+g+b)/3);
  632. }
  633. }
  634.  
  635. // Get the current time again and compute the time difference [s]
  636. t = ((double)getTickCount() - t) / getTickFrequency();
  637. // Print (in the console window) the processing time in [ms]
  638. printf("Time = %.3f [ms]\n", t * 1000);
  639.  
  640. imshow("input image", src);
  641. imshow("gray image", dst);
  642. waitKey();
  643. destroyAllWindows();
  644. }
  645. }
  646.  
  647. /* LAB 3*/
  648.  
  649. void showHistogram(const string& name, int* hist, const int hist_cols,
  650. const int hist_height) {
  651.  
  652. Mat imgHist(hist_height, hist_cols, CV_8UC3, CV_RGB(255, 255, 255));
  653. // constructs a white image
  654.  
  655. //computes histogram maximum
  656. int max_hist = 0;
  657. for (int i = 0; i<hist_cols; i++)
  658. if (hist[i] > max_hist)
  659. max_hist = hist[i];
  660. double scale = 1.0;
  661. scale = (double)hist_height / max_hist;
  662. int baseline = hist_height - 1;
  663. for (int x = 0; x < hist_cols; x++) {
  664. Point p1 = Point(x, baseline);
  665. Point p2 = Point(x, baseline - cvRound(hist[x] * scale));
  666. line(imgHist, p1, p2, CV_RGB(255, 0, 255)); // histogram bins
  667. // colored in magenta
  668.  
  669. }
  670. imshow(name, imgHist);
  671. }
  672.  
  673. void showHistogram(const string& name, double* hist, const int hist_cols,
  674. const int hist_height, const int vline1 = -1, const int vline2 = -1) {
  675.  
  676. Mat imgHist(hist_height, hist_cols, CV_8UC3, CV_RGB(255, 255, 255));
  677. // constructs a white image
  678.  
  679. //computes histogram maximum
  680. double max_hist = 0;
  681. for (int i = 0; i<hist_cols; i++)
  682. if (hist[i] > max_hist)
  683. max_hist = hist[i];
  684. double scale = 1.0;
  685. scale = hist_height / max_hist;
  686. double baseline = hist_height - 1;
  687. for (int x = 0; x < hist_cols; x++) {
  688. Point p1 = Point(x, baseline);
  689. Point p2 = Point(x, baseline - cvRound(hist[x] * scale));
  690. line(imgHist, p1, p2, CV_RGB(0, 0, 0)); // histogram bins
  691. // colored in magenta
  692.  
  693. }
  694.  
  695. if(vline1 != -1)
  696. {
  697. Point p1 = Point(vline1, baseline);
  698. Point p2 = Point(vline1, baseline - 255);
  699. line(imgHist, p1, p2, CV_RGB(0, 127, 255));
  700. }
  701.  
  702. if (vline2 != -1)
  703. {
  704. Point p1 = Point(vline2, baseline);
  705. Point p2 = Point(vline2, baseline - 255);
  706. line(imgHist, p1, p2, CV_RGB(255, 127, 0));
  707. }
  708.  
  709. imshow(name, imgHist);
  710. }
  711.  
  712.  
  713. int clamp(int v, int minv = 0, int maxv = 255)
  714. {
  715. if (v < minv) return minv;
  716. if (v > maxv) return maxv;
  717. return v;
  718. }
  719.  
  720. void testL3Hist14()
  721. {
  722. char fname[MAX_PATH];
  723. while (openFileDlg(fname))
  724. {
  725. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  726. int height = src.rows;
  727. int width = src.cols;
  728.  
  729. imshow("input image", src);
  730. waitKey(10);
  731.  
  732. int* hist = (int*)malloc(sizeof(int) * 256);
  733. memset(hist, 0, sizeof(int) * 256);
  734.  
  735. for (int i = 0; i < height; i++)
  736. {
  737. for (int j = 0; j < width; j++)
  738. {
  739. hist[src.at<uchar>(i, j)]++;
  740. }
  741. }
  742. showHistogram("Standard", hist, 256, 200);
  743.  
  744. double* histD = (double*)malloc(sizeof(double) * 256);
  745.  
  746. double maxh = 0.0;
  747. for (int i = 0; i < 256; i++)
  748. if (hist[i] > maxh)
  749. maxh = hist[i];
  750.  
  751. for (int i = 0; i < 256; i++)
  752. histD[i] = hist[i] / maxh;
  753.  
  754. showHistogram("Normalized", histD, 256, 200);
  755. waitKey(10);
  756.  
  757. int m = 0;
  758.  
  759. while (true)
  760. {
  761. cout << "Dati m: ";
  762. cin >> m;
  763. if (m == -1) break;
  764.  
  765. int divFact = 256 / m + 1;
  766. int* histR = (int*)malloc(sizeof(int) * m);
  767. memset(histR, 0, sizeof(int) * m);
  768.  
  769. for (int i = 0; i < 256; i++)
  770. histR[i / divFact] += hist[i];
  771.  
  772. showHistogram("Reduced", histR, m, 200);
  773. waitKey(0);
  774. free(histR);
  775. }
  776.  
  777. free(hist);
  778. free(histD);
  779.  
  780. waitKey();
  781. destroyAllWindows();
  782. }
  783. }
  784.  
  785. int* calcHistogram(Mat imag)
  786. {
  787. int height = imag.rows;
  788. int width = imag.cols;
  789.  
  790. int* hist = (int*)malloc(sizeof(int) * 256);
  791. memset(hist, 0, sizeof(int) * 256);
  792.  
  793. for (int i = 0; i < height; i++)
  794. {
  795. for (int j = 0; j < width; j++)
  796. {
  797. hist[imag.at<uchar>(i, j)]++;
  798. }
  799. }
  800. return hist;
  801.  
  802. }
  803.  
  804. /*
  805. * Normalised Values
  806. */
  807. double* calcNHistogram(Mat imag)
  808. {
  809. int height = imag.rows;
  810. int width = imag.cols;
  811.  
  812. int* hist = calcHistogram(imag);
  813.  
  814.  
  815. double* histD = (double*)malloc(sizeof(double) * 256);
  816.  
  817. double maxh = 0.0;
  818. for (int i = 0; i < 256; i++)
  819. if (hist[i] > maxh)
  820. maxh = hist[i];
  821.  
  822. for (int i = 0; i < 256; i++)
  823. histD[i] = hist[i] / maxh;
  824.  
  825. free(hist);
  826.  
  827. return histD;
  828.  
  829. }
  830.  
  831. /*
  832. * Normalised sum
  833. */
  834. double* calcNHistogram(int* imagHist, int width, int height)
  835. {
  836. double* histD = (double*)malloc(sizeof(double) * 256);
  837.  
  838. double maxh = width * height;
  839. /*for (int i = 0; i < 256; i++)
  840. if (imagHist[i] > maxh)
  841. maxh = imagHist[i];*/
  842.  
  843. for (int i = 0; i < 256; i++)
  844. histD[i] = imagHist[i] / maxh;
  845.  
  846. return histD;
  847.  
  848. }
  849.  
  850. /*Warning possible out of bounds error*/
  851. int* findPeaks(double* histD, int wh, double thresh, int* num_max = NULL )
  852. {
  853. int* maxime = (int*)malloc(sizeof(int) * 256);
  854. int lastmaxim = 1;
  855. maxime[0] = 0;
  856.  
  857. for (int i = wh; i < 256 - wh; i++)
  858. {
  859. double local_sum = 0.0;
  860. double local_max = 0.0;
  861. for (int j = -wh; j <= wh; j++)
  862. {
  863. if (histD[i + j] > local_max)
  864. local_max = histD[i + j];
  865. local_sum += histD[i + j];
  866. }
  867.  
  868. local_sum /= 2.0 * wh + 1.0;
  869.  
  870. if (histD[i] > local_sum + thresh && histD[i] >= local_max)
  871. maxime[lastmaxim++] = i;
  872. }
  873.  
  874. maxime[lastmaxim++] = 255;
  875.  
  876. if(num_max != NULL)
  877. (*num_max) = lastmaxim;
  878.  
  879. return maxime;
  880. }
  881.  
  882. void testL3Bins56()
  883. {
  884. char fname[MAX_PATH];
  885. while (openFileDlg(fname))
  886. {
  887. Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  888. int height = src.rows;
  889. int width = src.cols;
  890.  
  891. imshow("input image", src);
  892. waitKey(10);
  893.  
  894. int* hist = calcHistogram(src);
  895.  
  896. double* histD = calcNHistogram(hist, width, height);
  897.  
  898. showHistogram("Normalized", histD, 256, 200);
  899. waitKey(10);
  900.  
  901. int wh = 5;
  902. double thresh = 0.0003;
  903. int lastmaxim;
  904. int* maxime = findPeaks(histD, 5, 0.0003, &lastmaxim);
  905. //maxime[lastmaxim++] = 255;
  906.  
  907.  
  908. Mat dst = Mat(height, width, CV_8UC1);
  909.  
  910. for (int i = 0; i < height; i++)
  911. {
  912. for (int j = 0; j < width; j++)
  913. {
  914. int cval = src.at<uchar>(i, j);
  915. int fval = 255;
  916. for(int k=1; k < lastmaxim; k++)
  917. if(cval <= maxime[k])
  918. {
  919. fval = cval - maxime[k-1] < maxime[k] - cval ? maxime[k-1] : maxime[k];
  920. break;
  921. }
  922.  
  923. dst.at<uchar>(i, j) = fval;
  924. }
  925. }
  926.  
  927. imshow("Reduced image", dst);
  928. waitKey(10);
  929.  
  930. int* histRed = (int*)malloc(sizeof(int) * 256);
  931. memset(histRed, 0, sizeof(int) * 256);
  932.  
  933. for (int i = 0; i < height; i++)
  934. {
  935. for (int j = 0; j < width; j++)
  936. {
  937. histRed[dst.at<uchar>(i, j)]++;
  938. }
  939. }
  940.  
  941. showHistogram("Reduced Hist", histRed, 256, 200);
  942. waitKey(10);
  943.  
  944.  
  945.  
  946.  
  947. //Floyd
  948. Mat dstCorr = Mat(height, width, CV_8UC1);
  949.  
  950. const int WH = 5;
  951. const float TH = 0.0003;
  952. int roi_size = 2 * WH + 1;
  953.  
  954. std::vector<int> maximum_values;
  955. for (int k = 0 + WH; k <= 255 - WH; k++)
  956. {
  957. float v = 0;
  958. bool greaterThan = true;
  959. for (int j = k - WH; j <= k + WH; j++)
  960. {
  961. v += histD[j];
  962. if (histD[k] < histD[j])
  963. greaterThan = false;
  964. }
  965. v /= roi_size;
  966. if (histD[k] > v + TH && greaterThan)
  967. maximum_values.push_back(k);
  968. }
  969. maximum_values.insert(maximum_values.begin(), 0);
  970. maximum_values.insert(maximum_values.end(), 255); //possible error
  971.  
  972. /*Second Step*/
  973. for (int i = 1; i <= height - 2; i++)
  974. {
  975. for (int j = 1; j <= width - 2; j++)
  976. {
  977. int v = (int)dst.at<uchar>(i, j);
  978. int closest = 9999999;
  979. for (int l = 1; l < maximum_values.size(); l++)
  980. if (v <= maximum_values[l]) {
  981. closest = maximum_values[l] - v < v - maximum_values[l - 1] ? maximum_values[l] : maximum_values[l - 1];
  982. break;
  983. }
  984. dstCorr.at<uchar>(i, j) = closest;
  985.  
  986. double error = v - closest;
  987. dstCorr.at<uchar>(i, j + 1) = min(255, max(0, dstCorr.at<uchar>(i, j + 1) + (int)(7 * error / 16)));
  988. dstCorr.at<uchar>(i + 1, j - 1) = min(255, max(0, dstCorr.at<uchar>(i + 1, j - 1) + (int)(3 * error / 16)));
  989. dstCorr.at<uchar>(i + 1, j) = min(255, max(0, dstCorr.at<uchar>(i + 1, j) + (int)(5 * error / 16)));
  990. dstCorr.at<uchar>(i + 1, j + 1) = min(255, max(0, dstCorr.at<uchar>(i + 1, j + 1) + (int)(error / 16)));
  991.  
  992. }
  993. }
  994.  
  995. imshow("Floyd Steinber Image", dstCorr);
  996.  
  997. double* histN = calcNHistogram(dst);
  998. showHistogram("Floyd", histN, 256, 200);
  999.  
  1000. free(hist);
  1001. free(histD);
  1002.  
  1003. waitKey();
  1004. destroyAllWindows();
  1005. }
  1006. }
  1007.  
  1008.  
  1009. void floyd_steinberg_dithering()
  1010. {
  1011. char fname[MAX_PATH];
  1012. while (openFileDlg(fname))
  1013. {
  1014. Mat src = imread(fname, CV_8UC1);
  1015. Mat dst = src.clone();
  1016. Mat dstpart = src.clone();
  1017. int height = src.rows;
  1018. int width = src.cols;
  1019. const int WH = 5;
  1020. const float TH = 0.0003;
  1021. int roi_size = 2 * WH + 1;
  1022.  
  1023. /*First Step*/
  1024. int* hist = calcHistogram(src);
  1025.  
  1026. showHistogram("Orig", hist, 256, 200);
  1027.  
  1028. double* histogram_fdp = calcNHistogram(hist, width, height);
  1029.  
  1030.  
  1031. std::vector<int> maximum_values;
  1032. for (int k = 0 + WH; k <= 255 - WH; k++)
  1033. {
  1034. float v = 0;
  1035. bool greaterThan = true;
  1036. for (int j = k - WH; j <= k + WH; j++)
  1037. {
  1038. v += histogram_fdp[j];
  1039. if (histogram_fdp[k] < histogram_fdp[j])
  1040. greaterThan = false;
  1041. }
  1042. v /= roi_size;
  1043. if (histogram_fdp[k] > v + TH && greaterThan)
  1044. maximum_values.push_back(k);
  1045. }
  1046. maximum_values.insert(maximum_values.begin(), 0);
  1047. maximum_values.insert(maximum_values.end(), 255);
  1048.  
  1049.  
  1050. for (int i = 0; i < height; i++)
  1051. {
  1052. for (int j = 0; j < width; j++)
  1053. {
  1054. int v = (int)dst.at<uchar>(i, j);
  1055. int closest = 9999999;
  1056. for (int l = 1; l < maximum_values.size(); l++)
  1057. if (v <= maximum_values[l]) {
  1058. closest = maximum_values[l] - v < v - maximum_values[l - 1] ? maximum_values[l] : maximum_values[l - 1];
  1059. break;
  1060. }
  1061. dstpart.at<uchar>(i, j) = closest;
  1062. }
  1063. }
  1064.  
  1065. double* histR = calcNHistogram(dstpart);
  1066. showHistogram("Reduced", histR, 256, 200);
  1067.  
  1068. imshow("Reduced Image", dstpart);
  1069. /*Second Step*/
  1070. for (int i = 1; i <= height - 2; i++)
  1071. {
  1072. for (int j = 1; j <= width - 2; j++)
  1073. {
  1074. int v = (int)dst.at<uchar>(i, j);
  1075. int closest = 9999999;
  1076. for (int l = 1; l < maximum_values.size(); l++)
  1077. if (v <= maximum_values[l]) {
  1078. closest = maximum_values[l] - v < v - maximum_values[l - 1] ? maximum_values[l] : maximum_values[l - 1];
  1079. break;
  1080. }
  1081. dst.at<uchar>(i, j) = closest;
  1082.  
  1083. double error = v - closest;
  1084. dst.at<uchar>(i, j + 1) = min(255, max(0, dst.at<uchar>(i, j + 1) + (int)(7 * error / 16)));
  1085. dst.at<uchar>(i + 1, j - 1) = min(255, max(0, dst.at<uchar>(i + 1, j - 1) + (int)(3 * error / 16)));
  1086. dst.at<uchar>(i + 1, j) = min(255, max(0, dst.at<uchar>(i + 1, j) + (int)(5 * error / 16)));
  1087. dst.at<uchar>(i + 1, j + 1) = min(255, max(0, dst.at<uchar>(i + 1, j + 1) + (int)(error / 16)));
  1088.  
  1089. }
  1090. }
  1091.  
  1092. double* histN = calcNHistogram(dst);
  1093. showHistogram("Floyd", histN, 256, 200);
  1094.  
  1095. imshow("Floyd Steinber Image", dst);
  1096. waitKey();
  1097. destroyAllWindows();
  1098. }
  1099. }
  1100.  
  1101. void testL3Reduce7()
  1102. {
  1103. char fname[MAX_PATH];
  1104. while (openFileDlg(fname))
  1105. {
  1106. Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
  1107. int height = src.rows;
  1108. int width = src.cols;
  1109.  
  1110. Mat inter = Mat(height, width, CV_8UC3);
  1111. cvtColor(src, inter, CV_BGR2HSV);
  1112.  
  1113. Mat dst = Mat(height, width, CV_8UC3);
  1114.  
  1115. imshow("input image", src);
  1116. waitKey(10);
  1117.  
  1118. int* hist = (int*)malloc(sizeof(int) * 256);
  1119. memset(hist, 0, sizeof(int) * 256);
  1120.  
  1121. for (int i = 0; i < height; i++)
  1122. {
  1123. for (int j = 0; j < width; j++)
  1124. {
  1125. hist[inter.at<Vec3b>(i, j)[0]]++;
  1126. }
  1127. }
  1128.  
  1129. double* histD = (double*)malloc(sizeof(double) * 256);
  1130.  
  1131. double maxh = 0.0;
  1132. for (int i = 0; i < 256; i++)
  1133. if (hist[i] > maxh)
  1134. maxh = hist[i];
  1135.  
  1136. for (int i = 0; i < 256; i++)
  1137. histD[i] = hist[i] / maxh;
  1138.  
  1139. showHistogram("Normalized", histD, 256, 200);
  1140. waitKey(10);
  1141.  
  1142. int wh = 5;
  1143. double thresh = 0.5;
  1144. int maxime[256]; int lastmaxim = 1;
  1145. maxime[0] = 0;
  1146.  
  1147. for (int i = wh; i < 256 - wh; i++)
  1148. {
  1149. double local_sum = 0.0;
  1150. for (int j = -wh; j <= wh; j++)
  1151. {
  1152. local_sum += histD[i + j];
  1153. }
  1154.  
  1155. local_sum /= 2 * wh + 1;
  1156.  
  1157. if (histD[i] > local_sum + thresh)
  1158. maxime[lastmaxim++] = i;
  1159. }
  1160.  
  1161. maxime[lastmaxim++] = 255;
  1162. //maxime[lastmaxim++] = 255;
  1163.  
  1164.  
  1165.  
  1166.  
  1167. for (int i = 0; i < height; i++)
  1168. {
  1169. for (int j = 0; j < width; j++)
  1170. {
  1171. int cval = inter.at<Vec3b>(i, j)[0];
  1172. int fval = 255;
  1173. for (int k = 0; k < lastmaxim - 1; k++)
  1174. if (cval >= maxime[k])
  1175. fval = cval - maxime[k] < maxime[k + 1] - cval ? maxime[k] : maxime[k + 1];
  1176.  
  1177. inter.at<Vec3b>(i, j)[0] = fval;
  1178. }
  1179. }
  1180.  
  1181. cvtColor(inter, dst, CV_HSV2BGR);
  1182. imshow("Converted image", dst);
  1183.  
  1184. free(hist);
  1185. free(histD);
  1186.  
  1187. waitKey();
  1188. destroyAllWindows();
  1189. }
  1190. }
  1191.  
  1192. /* Other things*/
  1193. void testResize()
  1194. {
  1195. char fname[MAX_PATH];
  1196. while(openFileDlg(fname))
  1197. {
  1198. Mat src;
  1199. src = imread(fname);
  1200. Mat dst1,dst2;
  1201. //without interpolation
  1202. resizeImg(src,dst1,320,false);
  1203. //with interpolation
  1204. resizeImg(src,dst2,320,true);
  1205. imshow("input image",src);
  1206. imshow("resized image (without interpolation)",dst1);
  1207. imshow("resized image (with interpolation)",dst2);
  1208. waitKey();
  1209. }
  1210. }
  1211.  
  1212. void testCanny()
  1213. {
  1214. char fname[MAX_PATH];
  1215. while(openFileDlg(fname))
  1216. {
  1217. Mat src,dst,gauss;
  1218. src = imread(fname,CV_LOAD_IMAGE_GRAYSCALE);
  1219. double k = 0.4;
  1220. int pH = 50;
  1221. int pL = (int) k*pH;
  1222. GaussianBlur(src, gauss, Size(5, 5), 0.8, 0.8);
  1223. Canny(gauss,dst,pL,pH,3);
  1224. imshow("input image",src);
  1225. imshow("canny",dst);
  1226. waitKey();
  1227. }
  1228. }
  1229.  
  1230. void testVideoSequence()
  1231. {
  1232. VideoCapture cap("Videos/rubic.avi"); // off-line video from file
  1233. //VideoCapture cap(0); // live video from web cam
  1234. if (!cap.isOpened()) {
  1235. printf("Cannot open video capture device.\n");
  1236. waitKey(0);
  1237. return;
  1238. }
  1239.  
  1240. Mat edges;
  1241. Mat frame;
  1242. char c;
  1243.  
  1244. while (cap.read(frame))
  1245. {
  1246. Mat grayFrame;
  1247. cvtColor(frame, grayFrame, CV_BGR2GRAY);
  1248. Canny(grayFrame,edges,40,100,3);
  1249. imshow("source", frame);
  1250. imshow("gray", grayFrame);
  1251. imshow("edges", edges);
  1252. c = cvWaitKey(0); // waits a key press to advance to the next frame
  1253. if (c == 27) {
  1254. // press ESC to exit
  1255. printf("ESC pressed - capture finished\n");
  1256. break; //ESC pressed
  1257. };
  1258. }
  1259. }
  1260.  
  1261.  
  1262. void testSnap()
  1263. {
  1264. VideoCapture cap(0); // open the deafult camera (i.e. the built in web cam)
  1265. if (!cap.isOpened()) // openenig the video device failed
  1266. {
  1267. printf("Cannot open video capture device.\n");
  1268. return;
  1269. }
  1270.  
  1271. Mat frame;
  1272. char numberStr[256];
  1273. char fileName[256];
  1274.  
  1275. // video resolution
  1276. Size capS = Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH),
  1277. (int)cap.get(CV_CAP_PROP_FRAME_HEIGHT));
  1278.  
  1279. // Display window
  1280. const char* WIN_SRC = "Src"; //window for the source frame
  1281. namedWindow(WIN_SRC, CV_WINDOW_AUTOSIZE);
  1282. cvMoveWindow(WIN_SRC, 0, 0);
  1283.  
  1284. const char* WIN_DST = "Snapped"; //window for showing the snapped frame
  1285. namedWindow(WIN_DST, CV_WINDOW_AUTOSIZE);
  1286. cvMoveWindow(WIN_DST, capS.width + 10, 0);
  1287.  
  1288. char c;
  1289. int frameNum = -1;
  1290. int frameCount = 0;
  1291.  
  1292. for (;;)
  1293. {
  1294. cap >> frame; // get a new frame from camera
  1295. if (frame.empty())
  1296. {
  1297. printf("End of the video file\n");
  1298. break;
  1299. }
  1300.  
  1301. ++frameNum;
  1302.  
  1303. imshow(WIN_SRC, frame);
  1304.  
  1305. c = cvWaitKey(10); // waits a key press to advance to the next frame
  1306. if (c == 27) {
  1307. // press ESC to exit
  1308. printf("ESC pressed - capture finished");
  1309. break; //ESC pressed
  1310. }
  1311. if (c == 115){ //'s' pressed - snapp the image to a file
  1312. frameCount++;
  1313. fileName[0] = NULL;
  1314. sprintf(numberStr, "%d", frameCount);
  1315. strcat(fileName, "Images/A");
  1316. strcat(fileName, numberStr);
  1317. strcat(fileName, ".bmp");
  1318. bool bSuccess = imwrite(fileName, frame);
  1319. if (!bSuccess)
  1320. {
  1321. printf("Error writing the snapped image\n");
  1322. }
  1323. else
  1324. imshow(WIN_DST, frame);
  1325. }
  1326. }
  1327.  
  1328. }
  1329.  
  1330. void MyCallBackFunc(int event, int x, int y, int flags, void* param)
  1331. {
  1332. //More examples: http://opencvexamples.blogspot.com/2014/01/detect-mouse-clicks-and-moves-on-image.html
  1333. Mat* src = (Mat*)param;
  1334. if (event == CV_EVENT_LBUTTONDOWN)
  1335. {
  1336. printf("Pos(x,y): %d,%d Color(RGB): %d,%d,%d\n",
  1337. x, y,
  1338. (int)(*src).at<Vec3b>(y, x)[2],
  1339. (int)(*src).at<Vec3b>(y, x)[1],
  1340. (int)(*src).at<Vec3b>(y, x)[0]);
  1341. }
  1342. }
  1343.  
  1344. void testMouseClick()
  1345. {
  1346. Mat src;
  1347. // Read image from file
  1348. char fname[MAX_PATH];
  1349. while (openFileDlg(fname))
  1350. {
  1351. src = imread(fname);
  1352. //Create a window
  1353. namedWindow("My Window", 1);
  1354.  
  1355. //set the callback function for any mouse event
  1356. setMouseCallback("My Window", MyCallBackFunc, &src);
  1357.  
  1358. //show the image
  1359. imshow("My Window", src);
  1360.  
  1361. // Wait until user press some key
  1362. waitKey(0);
  1363. }
  1364. }
  1365.  
  1366. boolean isPerim(Mat imag, int x, int y, Vec3b bgCol)
  1367. {
  1368. int neigh[] = { -1,0,1 };
  1369.  
  1370. for(int dy = 0; dy < 3; dy++)
  1371. for(int dx = 0; dx < 3; dx++)
  1372. {
  1373. int nx = x + neigh[dx];
  1374. int ny = y + neigh[dy];
  1375.  
  1376. if (ny >= imag.rows || nx >= imag.cols || ny < 0 || nx < 0)
  1377. continue;
  1378.  
  1379. if (imag.at<Vec3b>(ny, nx) == bgCol)
  1380. return true;
  1381.  
  1382. }
  1383. return false;
  1384. }
  1385.  
  1386. void processObjHandler(int event, int mx, int my, int flags, void* param)
  1387. {
  1388. if (event != EVENT_LBUTTONDOWN) return;
  1389.  
  1390. Mat src = *(Mat*)param;
  1391. Mat objOnly = Mat(src.rows, src.cols, CV_8UC3);
  1392. Mat proiectii = Mat(src.rows, src.cols, CV_8UC3);
  1393.  
  1394. int height = src.rows;
  1395. int width = src.cols;
  1396.  
  1397. int* pry = (int*)malloc(sizeof(int) * height);
  1398. int* prx = (int*)malloc(sizeof(int) * width);
  1399.  
  1400. memset(pry, 0, sizeof(int) * height);
  1401. memset(prx, 0, sizeof(int) * width);
  1402.  
  1403. Vec3b bgcol = src.at<Vec3b>(0, 0);
  1404.  
  1405. Vec3b objcol = src.at<Vec3b>(my, mx);
  1406.  
  1407. //std::vector<Point2i> points;
  1408. //std::vector<Point2i> perimPoints;
  1409.  
  1410. int area = 0;
  1411. int perim = 0;
  1412. long avgx = 0, avgy = 0;
  1413. int minx = width;
  1414. int miny = height;
  1415. int maxx = 0;
  1416. int maxy = 0;
  1417.  
  1418. for (int y = 0; y < height; y++)
  1419. {
  1420. for (int x = 0; x < width; x++)
  1421. {
  1422. if (src.at<Vec3b>(y, x) != objcol) continue;
  1423.  
  1424. if (x > maxx) maxx = x;
  1425. if (y > maxy) maxy = y;
  1426. if (x < minx) minx = x;
  1427. if (y < miny) miny = y;
  1428.  
  1429. objOnly.at<Vec3b>(y, x) = objcol;
  1430. //points.emplace_back(x, y);
  1431. area++;
  1432. avgx += x;
  1433. avgy += y;
  1434. if (isPerim(src, x, y, bgcol))
  1435. {
  1436. perim++;
  1437. objOnly.at<Vec3b>(y, x) = Vec3b(0,0,0);
  1438. //perimPoints.emplace_back(x, y);
  1439. }
  1440.  
  1441. pry[y]++;
  1442. prx[x]++;
  1443. }
  1444. }
  1445.  
  1446. avgx /= area;
  1447. avgy /= area;
  1448.  
  1449. int deviatie = 0;
  1450. int devx = 0;
  1451. int devy = 0;
  1452.  
  1453. for (int y = 0; y < height; y++)
  1454. {
  1455. for (int x = 0; x < width; x++)
  1456. {
  1457. if (src.at<Vec3b>(y, x) != objcol) continue;
  1458.  
  1459. deviatie += (y - avgy) * (x - avgx);
  1460. devx += (x - avgx) * (x - avgx);
  1461. devy += (y - avgy) * (y - avgy);
  1462. }
  1463. }
  1464.  
  1465. double angle = atan2(2.0*deviatie, devx - devy) / 2.0;
  1466.  
  1467. for(double r = -40.0; r < 40.0; r += 1.0)
  1468. {
  1469. int cx = (int)(avgx + r * cos(angle));
  1470. int cy = (int)(avgy + r * sin(angle));
  1471.  
  1472. if (cy >= objOnly.rows || cx >= objOnly.cols || cy < 0 || cx < 0) continue;
  1473.  
  1474. objOnly.at<Vec3b>(cy, cx) = Vec3b(200, 200, 50);
  1475. }
  1476.  
  1477. for (int x = 0; x < width; x++)
  1478. for (int y = 0; y < height; y++)
  1479. {
  1480. proiectii.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
  1481. }
  1482.  
  1483. for(int y =0; y < height; y++)
  1484. for(int x = 0; x < pry[y]; x++)
  1485. {
  1486. proiectii.at<Vec3b>(y, x) += Vec3b(255, 127, 0);
  1487. }
  1488.  
  1489. for (int x = 0; x < width; x++)
  1490. for (int y = 0; y < prx[x]; y++)
  1491. {
  1492. proiectii.at<Vec3b>(y, x) += Vec3b(0, 127, 255);
  1493. }
  1494.  
  1495. /*Draw Center*/
  1496. int neigh[] = { -1,0,1 };
  1497.  
  1498. for (int dy = 0; dy < 3; dy++)
  1499. for (int dx = 0; dx < 3; dx++)
  1500. {
  1501. int nx = avgx + neigh[dx];
  1502. int ny = avgy + neigh[dy];
  1503.  
  1504. if (ny >= objOnly.rows || nx >= objOnly.cols || ny < 0 || nx < 0)
  1505. continue;
  1506.  
  1507. objOnly.at<Vec3b>(ny, nx) = Vec3b(255, 255, 0);
  1508. }
  1509.  
  1510. double asprat = 1.0 * (maxx - minx) / (maxy - miny);
  1511. double factsubt = 4.0 * PI * area / (perim * perim) ;
  1512.  
  1513. cout << "Centru de greutate (x,y): " << avgx << ", " << avgy << endl;
  1514. cout << "Arie: " << area << endl;
  1515. cout << "Perimetru: " << perim << endl;
  1516. cout << "Aspect Ratio: " << asprat << endl;
  1517. cout << "Factor de subtiere: " << factsubt << endl;
  1518. cout << "Unghi: " << angle * 180 / PI << endl;
  1519.  
  1520. cout << endl;
  1521. imshow("ObjOnly", objOnly);
  1522. waitKey(10);
  1523. imshow("Proiectii", proiectii);
  1524. waitKey(10);
  1525. }
  1526.  
  1527. void processObjects()
  1528. {
  1529. char fname[MAX_PATH];
  1530. while (openFileDlg(fname))
  1531. {
  1532. Mat src;
  1533. src = imread(fname, CV_LOAD_IMAGE_COLOR);
  1534.  
  1535. imshow("Orig Image", src);
  1536.  
  1537. setMouseCallback("Orig Image", processObjHandler, &src);
  1538.  
  1539. waitKey();
  1540. destroyAllWindows();
  1541. }
  1542. }
  1543.  
  1544.  
  1545. /*
  1546. * option values:
  1547. * 4 - four neighbours
  1548. * 8 - all neighbours
  1549. * 81 - all neighbours withou center
  1550. * -1 - previous neighbours
  1551. * 1 - future neighbours
  1552. */
  1553. vector<Point2i> getNeighbours(int x, int y, int width, int height, int option = 81)
  1554. {
  1555. vector<Point2i> points;
  1556.  
  1557. int neigh[] = { -1,0,1 };
  1558.  
  1559. for (int dy = 0; dy < 3; dy++)
  1560. for (int dx = 0; dx < 3; dx++)
  1561. {
  1562. int nx = x + neigh[dx];
  1563. int ny = y + neigh[dy];
  1564.  
  1565. if (nx < 0 || ny < 0 || nx >= width || ny>= height) continue;
  1566. //if (dx == 1 && dy == 1) continue;
  1567.  
  1568. if (option == 8)
  1569. points.emplace_back(nx, ny);
  1570. else if (option == 81 && dx != 1 && dy != 1)
  1571. points.emplace_back(nx, ny);
  1572. else if (option == 4 && (dx-1) * (dy-1) == 0)
  1573. points.emplace_back(nx, ny);
  1574. else if (option == -1 && (dy == 0 || dy == 1 && dx == 0))
  1575. points.emplace_back(nx, ny);
  1576. else if (option == 1 && !(dy == 0 || dy == 1 && dx == 0))
  1577. points.emplace_back(nx, ny);
  1578.  
  1579. }
  1580.  
  1581. return points;
  1582. }
  1583.  
  1584. void labelObjects()
  1585. {
  1586.  
  1587. Vec3b manyColors[256];
  1588.  
  1589. default_random_engine gen;
  1590. uniform_int_distribution<int> d(0, 255);
  1591.  
  1592. for (int i = 0; i < 256; i++)
  1593. manyColors[i] = Vec3b(d(gen), d(gen), d(gen));
  1594.  
  1595. char fname[MAX_PATH];
  1596. while (openFileDlg(fname))
  1597. {
  1598. Mat src, dst, gauss;
  1599. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  1600.  
  1601. int height = src.rows;
  1602. int width = src.cols;
  1603.  
  1604.  
  1605. dst = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1606.  
  1607. int label = 0;
  1608. Mat labels = Mat::zeros(cv::Size(width, height), CV_16SC1);
  1609.  
  1610. for(int y = 0; y < height; y++)
  1611. for(int x = 0; x < width; x++)
  1612. {
  1613. if (src.at<uchar>(y, x) == 0 && labels.at<short>(y, x) == 0)
  1614. {
  1615. label++;
  1616. queue<Point2i>Q;
  1617.  
  1618. dst.at<Vec3b>(y, x) = manyColors[label];
  1619.  
  1620. Q.push(Point2i(x, y));
  1621. labels.at<short>(y, x) = label;
  1622.  
  1623. while(!Q.empty())
  1624. {
  1625. Point2i cp = Q.front();
  1626. Q.pop();
  1627. auto neighbours = getNeighbours(cp.x, cp.y, width, height);
  1628. for (auto n : neighbours)
  1629. {
  1630. if (src.at<uchar>(n.y, n.x) == 0 && labels.at<short>(n.y, n.x) == 0)
  1631. {
  1632. Q.push(Point2i(n.x, n.y));
  1633. dst.at<Vec3b>(n.y, n.x) = manyColors[label];
  1634. labels.at<short>(n.y, n.x) = label;
  1635. }
  1636.  
  1637. }
  1638. }
  1639. }
  1640. }
  1641.  
  1642.  
  1643.  
  1644. imshow("input image", src);
  1645. imshow("labeled image", dst);
  1646. waitKey();
  1647. destroyAllWindows();
  1648. }
  1649. }
  1650.  
  1651. void labelObjects2Steps()
  1652. {
  1653.  
  1654. Vec3b manyColors[256];
  1655.  
  1656. default_random_engine gen;
  1657. uniform_int_distribution<int> d(0, 255);
  1658.  
  1659. for (int i = 0; i < 256; i++)
  1660. manyColors[i] = Vec3b(d(gen), d(gen), d(gen));
  1661.  
  1662. char fname[MAX_PATH];
  1663. while (openFileDlg(fname))
  1664. {
  1665. Mat src, dst, interm;
  1666. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  1667.  
  1668. int height = src.rows;
  1669. int width = src.cols;
  1670.  
  1671.  
  1672. dst = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1673. interm = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1674.  
  1675. int label = 0;
  1676. Mat labels = Mat::zeros(cv::Size(width, height), CV_16SC1);
  1677.  
  1678. vector<vector <int>> edges;
  1679.  
  1680. for (int y = 0; y < height; y++)
  1681. for (int x = 0; x < width; x++)
  1682. {
  1683. if (src.at<uchar>(y, x) != 0 || labels.at<short>(y, x) != 0) continue;
  1684.  
  1685. vector<int> L;
  1686.  
  1687. auto neighbours = getNeighbours(x, y, width, height, -1);
  1688. for (auto n : neighbours)
  1689. {
  1690. if (labels.at<short>(n.y, n.x) > 0)
  1691. L.push_back(labels.at<short>(n.y, n.x));
  1692. }
  1693.  
  1694. if (L.size() == 0)
  1695. {
  1696. label++;
  1697. labels.at<short>(y, x) = label;
  1698. interm.at<Vec3b>(y, x) = manyColors[label];
  1699.  
  1700. edges.resize(label + 1);
  1701. }
  1702. else
  1703. {
  1704. int minv = L[0];
  1705. for (int i = 0; i < L.size(); i++)
  1706. if (L[i] < minv)
  1707. minv = L[i];
  1708.  
  1709. labels.at<short>(y, x) = minv;
  1710. interm.at<Vec3b>(y, x) = manyColors[minv];
  1711.  
  1712. for (auto cl : L)
  1713. if (cl != minv)
  1714. {
  1715. edges[minv].push_back(cl);
  1716. edges[cl].push_back(minv);
  1717. }
  1718.  
  1719. }
  1720.  
  1721. }
  1722.  
  1723. int newlabel = 0;
  1724. int newlabels[256];
  1725. memset(newlabels, 0, 256 * sizeof(int));
  1726.  
  1727. for(int i = 1; i <= label; i++)
  1728. {
  1729. if(newlabels[i] == 0)
  1730. {
  1731. newlabel++;
  1732. queue<int> Q;
  1733.  
  1734. newlabels[i] = newlabel;
  1735.  
  1736. Q.push(i);
  1737.  
  1738. while(!Q.empty())
  1739. {
  1740. auto head = Q.front();
  1741. Q.pop();
  1742. for (auto edge : edges[head])
  1743. {
  1744. if (newlabels[edge] == 0)
  1745. {
  1746. newlabels[edge] = newlabel;
  1747. Q.push(edge);
  1748. }
  1749.  
  1750. }
  1751. }
  1752.  
  1753. }
  1754. }
  1755.  
  1756. for (int y = 0; y < height; y++)
  1757. for (int x = 0; x < width; x++)
  1758. {
  1759. labels.at<short>(y, x) = newlabels[labels.at<short>(y, x)];
  1760. dst.at<Vec3b>(y, x) = manyColors[labels.at<short>(y, x)];
  1761. }
  1762.  
  1763.  
  1764.  
  1765. imshow("input image", src);
  1766. imshow("1st image", interm);
  1767. imshow("labeled image", dst);
  1768. waitKey();
  1769. destroyAllWindows();
  1770. }
  1771. }
  1772.  
  1773. bool isInside(int width, int height, Point2i p)
  1774. {
  1775. return p.x >= 0 && p.y >= 0 && p.x < width && p.y < height;
  1776. }
  1777.  
  1778. /*
  1779. * option values:
  1780. * 4 - four neighbours
  1781. * 8 - all neighbours
  1782. */
  1783. bool nextNeigh(Point2i currentPoint, Point2i *neighbourPoint, int *dir, int option, int width, int height, int startingDir = -1)
  1784. {
  1785. static int lastDir = 0;
  1786.  
  1787. if (startingDir != -1)
  1788. {
  1789. lastDir = startingDir;
  1790. if (option == 4)
  1791. lastDir = (lastDir + 3) % 4;
  1792. if (option == 8)
  1793. lastDir = lastDir % 2 ? (lastDir + 6) % 8 : (lastDir + 7) % 8;
  1794. }
  1795.  
  1796. int ndx[] = { 1,1,0,-1,-1,-1,0,1 };
  1797. int ndy[] = { 0,1,1,1,0,-1,-1,-1 };
  1798.  
  1799. if(option == 4)
  1800. {
  1801. *dir = lastDir;
  1802. *neighbourPoint = Point2i(currentPoint.x + ndx[(*dir * 2) %8], currentPoint.y + ndy[(*dir * 2) % 8]*-1);
  1803. lastDir = (lastDir + 1) % 4;
  1804. return isInside(width, height, *neighbourPoint);
  1805. }
  1806.  
  1807. if (option == 8)
  1808. {
  1809. *dir = lastDir;
  1810. *neighbourPoint = Point2i(currentPoint.x + ndx[*dir%8], currentPoint.y + ndy[*dir % 8] * -1);
  1811. lastDir = (lastDir + 1) % 8;
  1812. return isInside(width, height, *neighbourPoint);
  1813. }
  1814.  
  1815. return false;
  1816. }
  1817.  
  1818. void findBorder()
  1819. {
  1820.  
  1821.  
  1822. char fname[MAX_PATH];
  1823. while (openFileDlg(fname))
  1824. {
  1825. Mat src, dst1, dst2;
  1826. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  1827.  
  1828. int height = src.rows;
  1829. int width = src.cols;
  1830.  
  1831.  
  1832. dst1 = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1833. dst2 = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1834.  
  1835. char bgCol = src.at<char>(0, 0);
  1836.  
  1837. //copy image to output
  1838. for (int y = 0; y < height; y++)
  1839. for (int x = 0; x < width; x++)
  1840. {
  1841. if (src.at<char>(y, x) != bgCol)
  1842. {
  1843. dst1.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
  1844. dst2.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
  1845. }else
  1846. {
  1847. dst1.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
  1848. dst2.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
  1849. }
  1850. }
  1851.  
  1852. vector<Point2i> points;
  1853. vector<int> directions;
  1854.  
  1855. for (int y = 0; y < height; y++)
  1856. for (int x = 0; x < width; x++)
  1857. if (src.at<char>(y, x) != bgCol)
  1858. {
  1859. points.emplace_back(x, y);
  1860. x = width;
  1861. y = height;
  1862. }
  1863.  
  1864. int dir = 7;
  1865. while(true)//cat timp nu s-a ajuns la inceput
  1866. {
  1867. Point2i currentPoint = points.back();
  1868. Point2i neighbourPoint;
  1869.  
  1870. bool inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 8, width, height, dir);
  1871.  
  1872. do {
  1873. if(inside)
  1874. if (src.at<char>(neighbourPoint.y, neighbourPoint.x) != bgCol)
  1875. {
  1876. dst1.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[0] = 255;
  1877. dst1.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[2] = 255;
  1878. points.push_back(neighbourPoint);
  1879. break;
  1880. }
  1881. inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 8, width, height);
  1882. } while (true);//cat timp nu a fost gasit un vecin
  1883.  
  1884. directions.push_back(dir);
  1885.  
  1886. if (points.size() > 2)
  1887. if (points[0] == points[points.size() - 2] && points[1] == points[points.size() - 1])
  1888. break;
  1889. }
  1890.  
  1891. cout << "8 vecini: ";
  1892. for (int i = 0; i < directions.size(); i++)
  1893. cout << directions[i] << " ";
  1894. cout << endl;
  1895. cout << "derivate: ";
  1896. for (int i = 1, cd = 0; i < directions.size(); i++)
  1897. cout << (directions[i] - directions[i - 1] < 0 ? directions[i] - directions[i - 1] + 8 : directions[i] - directions[i - 1]) << " ";
  1898. cout << endl;
  1899.  
  1900.  
  1901. points.clear();
  1902. directions.clear();
  1903.  
  1904. for (int y = 0; y < height; y++)
  1905. for (int x = 0; x < width; x++)
  1906. if (src.at<char>(y, x) != bgCol)
  1907. {
  1908. points.emplace_back(x, y);
  1909. x = width;
  1910. y = height;
  1911. }
  1912. dir = 0;
  1913. while (true)//cat timp nu s-a ajuns la inceput
  1914. {
  1915. Point2i currentPoint = points.back();
  1916. Point2i neighbourPoint;
  1917.  
  1918.  
  1919. bool inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 4, width, height, dir);
  1920.  
  1921. do {
  1922. if (inside)
  1923. if (src.at<char>(neighbourPoint.y, neighbourPoint.x) != bgCol)
  1924. {
  1925. dst2.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[2] = 255;
  1926. dst2.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[0] = 255;
  1927. points.push_back(neighbourPoint);
  1928. break;
  1929. }
  1930. inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 4, width, height);
  1931. } while (true);//cat timp nu a fost gasit un vecin
  1932.  
  1933. directions.push_back(dir);
  1934.  
  1935. if (points.size() > 2)
  1936. if (points[0] == points[points.size() - 2] && points[1] == points[points.size() - 1])
  1937. break;
  1938. }
  1939.  
  1940. cout << "4 vecini: ";
  1941. for (int i = 0; i < directions.size(); i++)
  1942. cout << directions[i] << " ";
  1943. cout << endl;
  1944. cout << "derivate: ";
  1945. for (int i = 1; i < directions.size(); i++)
  1946. cout << (directions[i] - directions[i - 1] < 0 ? directions[i] - directions[i - 1] + 4 : directions[i] - directions[i - 1]) << " ";
  1947. cout << endl;
  1948.  
  1949.  
  1950. imshow("input image", src);
  1951. imshow("cont4 image", dst2);
  1952. imshow("cont8 image", dst1);
  1953. waitKey();
  1954. destroyAllWindows();
  1955. }
  1956. }
  1957.  
  1958. void reconstruct()
  1959. {
  1960. int ndx[] = { 1,1,0,-1,-1,-1,0,1 };
  1961. int ndy[] = { 0,1,1,1,0,-1,-1,-1 };
  1962.  
  1963. ifstream inFile;
  1964. char fname[MAX_PATH];
  1965. while (openFileDlg(fname))
  1966. {
  1967. inFile.open("D:\\Projects\\Lab\\PI\\OpenCVApplication-VS2017_OCV340_basic\\Images\\l6\\reconstruct.txt");
  1968.  
  1969. Mat src, dst, interm;
  1970. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  1971.  
  1972. int height = src.rows;
  1973. int width = src.cols;
  1974.  
  1975.  
  1976. dst = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1977. interm = Mat::zeros(cv::Size(width, height), CV_8UC3);
  1978.  
  1979. int px, py;
  1980. inFile >> py;
  1981. inFile >> px;
  1982.  
  1983. int n;
  1984. inFile >> n;
  1985.  
  1986. int dir = 7;
  1987. for(int i = 0; i < n; i++)
  1988. {
  1989. int dDir;
  1990. inFile >> dir;
  1991.  
  1992. //dir = (dir + dDir) % 8;
  1993.  
  1994. px += ndx[dir];
  1995. py += ndy[dir];
  1996.  
  1997. if(isInside(src,py,px))
  1998. src.at<uchar>(height-py, px) = 255;
  1999. }
  2000.  
  2001.  
  2002. imshow("Reconstruction", src);
  2003. //imshow("1st image", interm);
  2004. //imshow("cont image", dst);
  2005. waitKey();
  2006. destroyAllWindows();
  2007. }
  2008. }
  2009.  
  2010. void dilate(Mat img, int option = 8)
  2011. {
  2012. Mat tmp = img.clone();
  2013. int height = tmp.rows;
  2014. int width = tmp.cols;
  2015.  
  2016. for(int y = 0; y < height; y++)
  2017. for (int x = 0; x < width; x++)
  2018. {
  2019. auto neigh = getNeighbours(x, y, width, height, option);
  2020. uchar maxc = 0;
  2021. for (auto n : neigh)
  2022. maxc = max(tmp.at<uchar>(n.y, n.x), maxc);
  2023.  
  2024. img.at<uchar>(y, x) = maxc;
  2025. }
  2026.  
  2027.  
  2028. }
  2029.  
  2030. void erode(Mat img, int option = 8)
  2031. {
  2032. Mat tmp = img.clone();
  2033. int height = tmp.rows;
  2034. int width = tmp.cols;
  2035.  
  2036. for (int y = 0; y < height; y++)
  2037. for (int x = 0; x < width; x++)
  2038. {
  2039. auto neigh = getNeighbours(x, y, width, height, option);
  2040. uchar minc = 255;
  2041. for (auto n : neigh)
  2042. minc = min(tmp.at<uchar>(n.y, n.x), minc);
  2043.  
  2044. img.at<uchar>(y, x) = minc;
  2045. }
  2046. }
  2047.  
  2048. void ed_open(Mat img, int option = 8)
  2049. {
  2050. erode(img, option);
  2051. dilate(img, option);
  2052. }
  2053.  
  2054.  
  2055. void ed_close(Mat img, int option = 8)
  2056. {
  2057. dilate(img, option);
  2058. erode(img, option);
  2059. }
  2060.  
  2061. void substract(Mat res, Mat a, Mat b)
  2062. {
  2063. if (a.rows != b.rows) return;
  2064. if (a.cols != b.cols) return;
  2065.  
  2066. int height = res.rows;
  2067. int width = res.cols;
  2068.  
  2069. for (int y = 0; y < height; y++)
  2070. for (int x = 0; x < width; x++)
  2071. res.at<uchar>(y, x) = max((int)a.at<uchar>(y, x) - (int)b.at<uchar>(y, x), 0);
  2072. }
  2073.  
  2074. void add(Mat res, Mat a, Mat b)
  2075. {
  2076. if (a.rows != b.rows) return;
  2077. if (a.cols != b.cols) return;
  2078.  
  2079. int height = res.rows;
  2080. int width = res.cols;
  2081.  
  2082. for (int y = 0; y < height; y++)
  2083. for (int x = 0; x < width; x++)
  2084. res.at<uchar>(y, x) = min((int)a.at<uchar>(y, x) + (int)b.at<uchar>(y, x), 255);
  2085. }
  2086.  
  2087. void invert(Mat res)
  2088. {
  2089. int height = res.rows;
  2090. int width = res.cols;
  2091.  
  2092. for (int y = 0; y < height; y++)
  2093. for (int x = 0; x < width; x++)
  2094. res.at<uchar>(y, x) = 255 -res.at<uchar>(y, x);
  2095. }
  2096.  
  2097. bool ed_cmp(Mat a, Mat b)
  2098. {
  2099. int height = a.rows;
  2100. int width = a.cols;
  2101.  
  2102. for (int y = 0; y < height; y++)
  2103. for (int x = 0; x < width; x++)
  2104. if (a.at<uchar>(y, x) != b.at<uchar>(y, x))
  2105. return false;
  2106. return true;
  2107. }
  2108.  
  2109. void EroDil()
  2110. {
  2111. char fname[MAX_PATH];
  2112. while (openFileDlg(fname))
  2113. {
  2114. Mat src, dil14, dil18, diln8, ero14, ero18, eron4, eron8, open1, openn, close1, closen;
  2115. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2116.  
  2117. int height = src.rows;
  2118. int width = src.cols;
  2119. int n;
  2120. cin >> n;
  2121.  
  2122. imshow("input image", src);
  2123.  
  2124. dil14 = src.clone();
  2125. dilate(dil14, 4);
  2126. imshow("1xdil4 image", dil14);
  2127.  
  2128. dil18 = src.clone();
  2129. dilate(dil18, 8);
  2130. imshow("1xdil8 image", dil18);
  2131.  
  2132. diln8 = src.clone();
  2133. for(int i =0; i < n; i++)
  2134. dilate(diln8, 8);
  2135. imshow("nxdil8 image", diln8);
  2136.  
  2137. ero14 = src.clone();
  2138. erode(ero14, 4);
  2139. imshow("1xero4 image", ero14);
  2140.  
  2141. ero18 = src.clone();
  2142. erode(ero18, 8);
  2143. imshow("1xero8 image", ero18);
  2144.  
  2145. eron8 = src.clone();
  2146. for (int i = 0; i < n; i++)
  2147. erode(eron8, 8);
  2148.  
  2149. imshow("nxero8 image", eron8);
  2150.  
  2151. open1 = src.clone();
  2152. ed_open(open1, 8);
  2153.  
  2154. imshow("1xopen image", open1);
  2155.  
  2156. openn = src.clone();
  2157. for (int i = 0; i < n; i++)
  2158. ed_open(openn, 8);
  2159.  
  2160. imshow("nxopen image", openn);
  2161.  
  2162.  
  2163. close1 = src.clone();
  2164. ed_close(close1, 8);
  2165.  
  2166. imshow("1xclose image", close1);
  2167.  
  2168. closen = src.clone();
  2169. for (int i = 0; i < n; i++)
  2170. ed_close(closen, 8);
  2171.  
  2172. imshow("nxclose image", closen);
  2173.  
  2174.  
  2175. waitKey();
  2176. destroyAllWindows();
  2177. }
  2178. }
  2179.  
  2180. void fillObjHandler(int event, int mx, int my, int flags, void* param)
  2181. {
  2182. if (event != EVENT_LBUTTONDOWN) return;
  2183.  
  2184. Mat src = *(Mat*)param;
  2185. int height = src.rows;
  2186. int width = src.cols;
  2187.  
  2188. if (src.at<uchar>(my, mx) == 0) return;
  2189.  
  2190. invert(src);
  2191.  
  2192. Mat tmp = Mat::zeros(cv::Size(width, height), CV_8UC1);
  2193. tmp.at<uchar>(my, mx) = 255;
  2194.  
  2195. Mat prev = tmp.clone();
  2196.  
  2197. while (true)
  2198. {
  2199. dilate(tmp);
  2200. substract(tmp, tmp, src);
  2201.  
  2202. if (ed_cmp(prev, tmp)) break;
  2203. prev = tmp.clone();
  2204.  
  2205. }
  2206.  
  2207. add(src, tmp, src);
  2208. invert(src);
  2209.  
  2210. imshow("Contour Image", src);
  2211. waitKey(10);
  2212. }
  2213.  
  2214. void FillEro()
  2215. {
  2216. char fname[MAX_PATH];
  2217. while (openFileDlg(fname))
  2218. {
  2219. Mat src, cont;
  2220. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2221. cont = src.clone();
  2222.  
  2223. dilate(cont);
  2224. substract(cont, cont, src);
  2225. invert(cont);
  2226.  
  2227. imshow("Orig Image", src);
  2228.  
  2229.  
  2230.  
  2231. imshow("Contour Image", cont);
  2232.  
  2233. setMouseCallback("Contour Image", fillObjHandler, &cont);
  2234.  
  2235. waitKey();
  2236. destroyAllWindows();
  2237. }
  2238. }
  2239.  
  2240. void imgStats()
  2241. {
  2242. char fname[MAX_PATH];
  2243. while (openFileDlg(fname))
  2244. {
  2245. Mat src, cont;
  2246. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2247.  
  2248. int height = src.rows;
  2249. int width = src.cols;
  2250.  
  2251. cont = src.clone();
  2252.  
  2253. int *hist = calcHistogram(src);
  2254. double *phist = calcNHistogram(hist, src.cols, src.rows);
  2255.  
  2256.  
  2257. int u = 0;
  2258.  
  2259. for (int i = 0; i < 255; i++)
  2260. u += i * hist[i];
  2261.  
  2262. u /= width * height;
  2263.  
  2264. cout << "Medie: " << u << endl;
  2265.  
  2266. int stddev = 0;
  2267. for (int i = 0; i < 255; i++)
  2268. for(int j = 0; j < hist[i]; j++)
  2269. stddev += (i - u)*(i - u);
  2270.  
  2271. stddev /= width * height;
  2272. stddev = sqrt(stddev);
  2273.  
  2274. cout << "Deviate Standard: " << stddev << endl;
  2275.  
  2276. showHistogram("PDF Orig", phist, 255, 200, u, u+stddev);
  2277.  
  2278. int *chist = calcHistogram(src);
  2279. for (int i = 1; i < 255; i++)
  2280. chist[i] += chist[i - 1];
  2281.  
  2282. showHistogram("CDF", chist, 255, 200);
  2283.  
  2284.  
  2285. imshow("Orig Image", src);
  2286. waitKey();
  2287. destroyAllWindows();
  2288. }
  2289. }
  2290.  
  2291. void autoBinarizeBimodal()
  2292. {
  2293. char fname[MAX_PATH];
  2294. while (openFileDlg(fname))
  2295. {
  2296. Mat src;
  2297. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2298.  
  2299. int height = src.rows;
  2300. int width = src.cols;
  2301.  
  2302. int *hist = calcHistogram(src);
  2303.  
  2304. double T = 127;
  2305. double minh = 255;
  2306. double maxh = 0;
  2307.  
  2308. for(int i = 0; i < 255; i++)
  2309. {
  2310. if (hist[i] > 0 && i < minh)minh = i;
  2311. if (hist[i] > 0 && i > maxh)maxh = i;
  2312. }
  2313.  
  2314. T = minh + maxh;
  2315. T /= 2;
  2316.  
  2317. double convergence = 0;
  2318. cout << "Prag conergenta: ";
  2319. cin >> convergence;
  2320.  
  2321. int umin, umax;
  2322. int smin, smax;
  2323. while(true)
  2324. {
  2325. umin = umax = 0;
  2326. smin = smax = 0;
  2327.  
  2328. for(int i = 0; i < 255; i++)
  2329. {
  2330. if (i < T) umin += i * hist[i], smin += hist[i];
  2331. if (i > T) umax += i * hist[i], smax += hist[i];
  2332. }
  2333.  
  2334. umin /= smin;
  2335. umax /= smax;
  2336.  
  2337. if (abs((umin + umax) / 2 - T) < convergence) break;
  2338.  
  2339. T = (umin + umax) / 2;
  2340. }
  2341.  
  2342. cout << "Pragul gasit: " << T << endl;
  2343.  
  2344. Mat binarized = Mat::zeros(cv::Size(width, height), CV_8UC1);
  2345.  
  2346.  
  2347. for (int y = 0; y < height; y++)
  2348. for (int x = 0; x < width; x++)
  2349. binarized.at<uchar>(y, x) = src.at<uchar>(y, x) > T ? 255 : 0;
  2350.  
  2351. imshow("Binarized", binarized);
  2352.  
  2353. waitKey();
  2354. destroyAllWindows();
  2355. }
  2356. }
  2357.  
  2358. void photoshop101()
  2359. {
  2360. char fname[MAX_PATH];
  2361. while (openFileDlg(fname))
  2362. {
  2363. Mat src;
  2364. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2365.  
  2366. imshow("Original", src);
  2367.  
  2368. int height = src.rows;
  2369. int width = src.cols;
  2370.  
  2371. int *hist = calcHistogram(src);
  2372. int *procHist;
  2373. int T = 127;
  2374. int minh = 255;
  2375. int maxh = 0;
  2376.  
  2377. for (int i = 0; i < 255; i++)
  2378. {
  2379. if (hist[i] > 0 && i < minh)minh = i;
  2380. if (hist[i] > 0 && i > maxh)maxh = i;
  2381. }
  2382.  
  2383. Mat negativ = src.clone();
  2384.  
  2385.  
  2386. for (int y = 0; y < height; y++)
  2387. for (int x = 0; x < width; x++)
  2388. negativ.at<uchar>(y, x) = 255 - src.at<uchar>(y, x);
  2389.  
  2390. imshow("Negativ", negativ);
  2391. procHist = calcHistogram(negativ);
  2392. showHistogram("Negativ Hist", procHist, 255, 200);
  2393.  
  2394.  
  2395. showHistogram("Original Hist", hist, 255, 200);
  2396. waitKey(10);
  2397.  
  2398.  
  2399.  
  2400. int omin, omax;
  2401. cout << "Minim iesire: "; cin >> omin;
  2402. cout << "Maxim iesire: "; cin >> omax;
  2403.  
  2404. double factor = 1.0*(omax - omin) / (maxh - minh);
  2405.  
  2406. Mat linScale = src.clone();
  2407.  
  2408. for (int y = 0; y < height; y++)
  2409. for (int x = 0; x < width; x++)
  2410. linScale.at<uchar>(y, x) = (int)max(min(omin + (src.at<uchar>(y, x) - minh)*factor, 255),0);
  2411.  
  2412. imshow("Linear Scale", linScale);
  2413. procHist = calcHistogram(linScale);
  2414. showHistogram("Linear Hist", procHist, 255, 200);
  2415. waitKey(10);
  2416.  
  2417.  
  2418. double gamma = 0.0;
  2419.  
  2420. cout << "Gamma correction: "; cin >> gamma;
  2421.  
  2422. Mat gammaCorrected = src.clone();
  2423.  
  2424. for (int y = 0; y < height; y++)
  2425. for (int x = 0; x < width; x++)
  2426. gammaCorrected.at<uchar>(y, x) = (int)(pow(src.at<uchar>(y, x)/255.0, gamma) * 255);
  2427.  
  2428. imshow("Gamma Corrected", gammaCorrected);
  2429. procHist = calcHistogram(gammaCorrected);
  2430. showHistogram("Gamma Hist", procHist, 255, 200);
  2431. waitKey(10);
  2432.  
  2433.  
  2434.  
  2435. int brightness = 0;
  2436.  
  2437. cout << "Brightness: "; cin >> brightness;
  2438.  
  2439. Mat brightened = src.clone();
  2440.  
  2441. for (int y = 0; y < height; y++)
  2442. for (int x = 0; x < width; x++)
  2443. brightened.at<uchar>(y, x) = (int)max(min(src.at<uchar>(y, x) + brightness, 255), 0);
  2444.  
  2445. imshow("Brightness Corrected", brightened);
  2446. procHist = calcHistogram(brightened);
  2447. showHistogram("Brightness Hist", procHist, 255, 200);
  2448.  
  2449.  
  2450. waitKey();
  2451. destroyAllWindows();
  2452. }
  2453. }
  2454.  
  2455. void equalizeHist()
  2456. {
  2457. char fname[MAX_PATH];
  2458. while (openFileDlg(fname))
  2459. {
  2460. Mat src;
  2461. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2462.  
  2463. imshow("Original", src);
  2464.  
  2465. int height = src.rows;
  2466. int width = src.cols;
  2467.  
  2468. int *hist = calcHistogram(src);
  2469. int *procHist;
  2470. int T = 127;
  2471. int minh = 255;
  2472. int maxh = 0;
  2473.  
  2474. for (int i = 0; i < 255; i++)
  2475. {
  2476. if (hist[i] > 0 && i < minh) minh = i;
  2477. if (hist[i] > 0 && i > maxh) maxh = i;
  2478. }
  2479.  
  2480. showHistogram("Original Hist", hist, 255, 200);
  2481. waitKey(10);
  2482.  
  2483. int *chist = calcHistogram(src);
  2484. double *nchist = calcNHistogram(chist, width, height);
  2485. int *reverse = calcHistogram(src);
  2486. for (int i = 1; i < 255; i++)
  2487. {
  2488. nchist[i] += nchist[i - 1];
  2489. }
  2490.  
  2491. for (int i = 1; i < 254; i++)
  2492. {
  2493. if ((int)(nchist[i + 1] * 255) > i || (int)(nchist[i - 1] * 255) < i)
  2494. reverse[i] = (int)(nchist[i] * 255);
  2495. else
  2496. reverse[i] = i;
  2497. }
  2498.  
  2499. showHistogram("CDF", nchist, 255, 200);
  2500.  
  2501. Mat equalized = src.clone();
  2502.  
  2503.  
  2504. for (int y = 0; y < height; y++)
  2505. for (int x = 0; x < width; x++)
  2506. equalized.at<uchar>(y, x) = reverse[src.at<uchar>(y, x)];
  2507.  
  2508. imshow("Equalized", equalized);
  2509. procHist = calcHistogram(equalized);
  2510. showHistogram("Equalized Hist", procHist, 255, 200);
  2511.  
  2512. nchist = calcNHistogram(procHist, width, height);
  2513. for (int i = 1; i < 255; i++)
  2514. nchist[i] += nchist[i - 1];
  2515.  
  2516. showHistogram("Equalized CDF", nchist, 255, 200);
  2517.  
  2518. waitKey(10);
  2519.  
  2520. waitKey();
  2521. destroyAllWindows();
  2522. }
  2523. }
  2524.  
  2525. void convolve(Mat res, Mat src, Mat filter, bool normalize = true, bool asDeltaMagnitude = false)
  2526. {
  2527. int height = src.rows;
  2528. int width = src.cols;
  2529.  
  2530. int f_height = (filter.rows - 1) / 2;
  2531. int f_width = (filter.cols - 1) / 2;
  2532.  
  2533. double sum = 0.0;
  2534. double sumn = 0.0;
  2535. for (int y = 0; y < filter.rows; y++)
  2536. for (int x = 0; x < filter.cols; x++)
  2537. if(filter.at<short>(y, x) > 0)
  2538. sum += filter.at<short>(y, x);
  2539. else
  2540. sumn -= filter.at<short>(y, x);
  2541.  
  2542. sum = sum + sumn;
  2543.  
  2544. for(int y = 0; y < height; y++)
  2545. for (int x = 0; x < width; x++)
  2546. {
  2547. double current_pixel = 0.0;
  2548. for(int dy =-f_height; dy <=f_height; dy++)
  2549. for (int dx = -f_width; dx <= f_width; dx++)
  2550. {
  2551. int cx = x + dx;
  2552. cx = cx < 0 ? 0 : cx;
  2553. cx = cx >= width ? width-1 : cx;
  2554.  
  2555. int cy = y + dy;
  2556. cy = cy < 0 ? 0 : cy;
  2557. cy = cy >= height ? height - 1 : cy;
  2558.  
  2559. current_pixel += (int)filter.at<short>(f_height + dy, f_width + dx) * src.at<uchar>(cy,cx);
  2560. }
  2561.  
  2562. if (abs(sum) > 0.01 & normalize)
  2563. {
  2564. current_pixel += sumn * 255;
  2565. current_pixel /= sum;
  2566. }
  2567.  
  2568. if (asDeltaMagnitude)
  2569. current_pixel = abs(current_pixel - 127) * 2;
  2570.  
  2571. current_pixel = current_pixel > 255 ? 255 : current_pixel;
  2572. current_pixel = current_pixel < 0 ? 0 : current_pixel;
  2573.  
  2574. res.at<uchar>(y, x) = (uchar)current_pixel;
  2575.  
  2576. }
  2577. }
  2578.  
  2579. Mat convolveImg(Mat img, Mat filter)
  2580. {
  2581.  
  2582. int height = img.rows;
  2583. int width = img.cols;
  2584.  
  2585. int fheight = filter.rows;
  2586. int fwidth = filter.cols;
  2587. int fsize = fwidth * fheight;
  2588.  
  2589. int fh_start = -fheight / 2;
  2590. int fh_end = fheight / 2;
  2591.  
  2592. int fw_start = -fwidth / 2;
  2593. int fw_end = fwidth / 2;
  2594.  
  2595. Mat res = Mat::zeros(height, width, CV_8UC1);
  2596.  
  2597. for(int y = 0; y < height; y++)
  2598. for (int x = 0; x < width; x++)
  2599. {
  2600. int sum = 0;
  2601. int count = fsize;
  2602. for (int fy = fh_start; fy < fh_end; fy++)
  2603. for (int fx = fw_start; fx < fw_end; fx++)
  2604. {
  2605. int nx = x + fx;
  2606. int ny = y + fy;
  2607. if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
  2608.  
  2609. int local_dif = img.at<uchar>(ny, nx) - filter.at<uchar>(fy - fh_start, fx - fw_start);
  2610. local_dif *= local_dif;
  2611.  
  2612. sum += local_dif;
  2613. count--;
  2614. }
  2615. sum /= fsize;
  2616.  
  2617. sum = sqrt(sum);
  2618. //sum *= sum;
  2619. //sum /= 255;
  2620. //sum = 255 - sum;
  2621. //sum += 127 * count / fsize;
  2622.  
  2623. res.at<uchar>(y, x) = (uchar)sum;
  2624.  
  2625. }
  2626.  
  2627. return res;
  2628. }
  2629.  
  2630. int convolveImgI(Mat img, Mat filter)
  2631. {
  2632.  
  2633. int height = img.rows;
  2634. int width = img.cols;
  2635.  
  2636. int fheight = filter.rows;
  2637. int fwidth = filter.cols;
  2638. int fsize = fwidth * fheight;
  2639.  
  2640. int fh_start = -(fheight / 2);
  2641. int fh_end = fheight / 2;
  2642.  
  2643. int fw_start = -(fwidth / 2);
  2644. int fw_end = fwidth / 2;
  2645.  
  2646. int total = 255 * 255;
  2647. int count_total = 0;
  2648.  
  2649. for (int y = 0; y < height; y++)
  2650. for (int x = 0; x < width; x++)
  2651. {
  2652. int sum = 0;
  2653. int count = fsize;
  2654. for (int fy = fh_start; fy < fh_end; fy++)
  2655. {
  2656. for (int fx = fw_start; fx < fw_end; fx++)
  2657. {
  2658. int nx = x + fx;
  2659. int ny = y + fy;
  2660. if (nx < 0 || nx >= width || ny < 0 || ny >= height)continue;
  2661.  
  2662. int local_dif = img.at<uchar>(ny, nx) - filter.at<uchar>(fy - fh_start, fx - fw_start);
  2663. local_dif *= local_dif;
  2664.  
  2665. sum += local_dif;
  2666. //count--;
  2667. }
  2668. }
  2669.  
  2670. sum /= fsize;
  2671.  
  2672. sum = sqrt(sum);
  2673. //sum *= sum;
  2674. //sum /= 255;
  2675. //sum = 255 - sum;
  2676. //sum += 127 * count / fsize;
  2677. count_total++;
  2678.  
  2679. total = sum < total ? sum : total;
  2680. }
  2681.  
  2682. //total /= count_total;
  2683.  
  2684. return total;
  2685. }
  2686.  
  2687. int total_conv(Mat img, Mat filter, int y)
  2688. {
  2689. int height = img.rows;
  2690. int width = img.cols;
  2691.  
  2692. int fheight = filter.rows;
  2693. int fwidth = filter.cols;
  2694. int fsize = fwidth * fheight;
  2695.  
  2696. int fh_start = -(fheight / 2);
  2697. int fh_end = fheight / 2;
  2698.  
  2699. int fw_start = -(fwidth / 2);
  2700. int fw_end = fwidth / 2;
  2701.  
  2702. int total = 255 * 255;
  2703.  
  2704.  
  2705. for (int x = 0; x < width; x++)
  2706. {
  2707. int sum = 0;
  2708.  
  2709. //#pragma omp parallel for reduction(+:sum)
  2710. for (int fy = fh_start; fy < fh_end; fy++)
  2711. {
  2712. for (int fx = fw_start; fx < fw_end; fx++)
  2713. {
  2714. int nx = x + fx;
  2715. int ny = y + fy;
  2716. if (nx < 0 || nx >= width || ny < 0 || ny >= height)continue;
  2717.  
  2718. int local_dif = img.at<uchar>(ny, nx) - filter.at<uchar>(fy - fh_start, fx - fw_start);
  2719. local_dif *= local_dif;
  2720.  
  2721. sum += local_dif;
  2722. }
  2723. }
  2724.  
  2725. sum /= fsize;
  2726.  
  2727. sum = sqrt(sum);
  2728. total = sum < total ? sum : total;
  2729. }
  2730.  
  2731. return total;
  2732. }
  2733.  
  2734. int convolveImgIP(Mat img, Mat filter)
  2735. {
  2736. int height = img.rows;
  2737. int* totals = (int*)malloc(4 * height);
  2738. int total = 255 * 255;
  2739.  
  2740. //#pragma omp parallel for
  2741. /*#pragma omp parallel sections
  2742. {
  2743. { if(height > 1) totals[0] = total_conv(img, filter, 0); }
  2744. #pragma omp section
  2745. { if (height > 2) totals[1] = total_conv(img, filter, 1); }
  2746. #pragma omp section
  2747. { if (height > 3) totals[2] = total_conv(img, filter, 2); }
  2748. #pragma omp section
  2749. { if (height > 4) totals[3] = total_conv(img, filter, 3); }
  2750. #pragma omp section
  2751. { if (height > 5) totals[4] = total_conv(img, filter, 4); }
  2752. }*/
  2753.  
  2754. for (int i = 0; i < height; i++)
  2755. totals[i] = total_conv(img, filter, i);
  2756.  
  2757. for (int i = 0; i < height; i++)
  2758. total = totals[i] < total ? totals[i] : total;
  2759.  
  2760. return total;
  2761. }
  2762.  
  2763.  
  2764. void lowHighPass()
  2765. {
  2766.  
  2767. char fname[MAX_PATH];
  2768. while (openFileDlg(fname))
  2769. {
  2770. Mat src;
  2771. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2772.  
  2773. imshow("Original", src);
  2774.  
  2775. int height = src.rows;
  2776. int width = src.cols;
  2777.  
  2778. Mat lowPassFilter = Mat(3, 3, CV_16SC1);
  2779.  
  2780. for(int y = 0; y < lowPassFilter.rows; y++)
  2781. for (int x = 0; x < lowPassFilter.cols; x++)
  2782. lowPassFilter.at<short>(y, x) = 1;
  2783.  
  2784.  
  2785. Mat gaussianFilter = Mat(3, 3, CV_16SC1);
  2786. for (int y = 0; y < 3; y++)
  2787. for (int x = 0; x < 3; x++)
  2788. {
  2789. if (x == 0 & y == 0 || x == 2 & y == 0 || x == 0 & y == 2 || x == 2 & y == 2)
  2790. gaussianFilter.at<short>(y, x) = 1;
  2791. if (x == 0 & y == 1 || x == 1 & y == 0 || x == 1 & y == 2 || x == 2 & y == 1)
  2792. gaussianFilter.at<short>(y, x) = 2;
  2793. if (x == 1 & y == 1)
  2794. gaussianFilter.at<short>(y, x) = 4;
  2795. }
  2796.  
  2797. Mat highPassFilter = Mat(3, 3, CV_16SC1);
  2798.  
  2799. for (int y = 0; y < highPassFilter.rows; y++)
  2800. for (int x = 0; x < highPassFilter.cols; x++)
  2801. highPassFilter.at<short>(y, x) = -1;
  2802.  
  2803. highPassFilter.at<short>(highPassFilter.rows/2, highPassFilter.cols/2) =
  2804. highPassFilter.rows * highPassFilter.cols;
  2805.  
  2806. Mat laplaceFilter = Mat(3, 3, CV_16SC1);
  2807. for (int y = 0; y < lowPassFilter.rows; y++)
  2808. for (int x = 0; x < lowPassFilter.cols; x++)
  2809. laplaceFilter.at<short>(y, x) = -1;
  2810.  
  2811. laplaceFilter.at<short>(laplaceFilter.rows / 2, laplaceFilter.cols / 2) =
  2812. laplaceFilter.rows * laplaceFilter.cols - 1;
  2813.  
  2814. Mat lowPass = src.clone();
  2815. convolve(lowPass, src, lowPassFilter);
  2816.  
  2817. imshow("LowPass", lowPass);
  2818. waitKey(10);
  2819.  
  2820. Mat gaussPass = src.clone();
  2821. convolve(gaussPass, src, gaussianFilter);
  2822.  
  2823. imshow("GaussPass", gaussPass);
  2824. waitKey(10);
  2825.  
  2826. Mat highPass = src.clone();
  2827. convolve(highPass, src, highPassFilter);
  2828.  
  2829. imshow("highPass", highPass);
  2830. waitKey(10);
  2831.  
  2832. Mat laplacePass = src.clone();
  2833. convolve(laplacePass, lowPass, laplaceFilter, false);
  2834.  
  2835. imshow("laplacePass", laplacePass);
  2836. waitKey(10);
  2837.  
  2838.  
  2839. waitKey();
  2840. destroyAllWindows();
  2841. }
  2842. }
  2843.  
  2844. void centering_transform(Mat src)
  2845. {
  2846. int height = src.rows;
  2847. int width = src.cols;
  2848.  
  2849. for (int y = 0; y < src.rows; y++)
  2850. for (int x = 0; x < src.cols; x++)
  2851. if ((x + y) % 2 == 1)
  2852. src.at<float>(y, x) = -src.at<float>(y, x);
  2853.  
  2854. }
  2855.  
  2856.  
  2857. Mat generic_frequency_domain_filter(Mat src) {
  2858. //imaginea trebuie să aibă elemente de tip float
  2859. Mat srcf;
  2860. src.convertTo(srcf, CV_32FC1);
  2861.  
  2862. //aplicarea transformatei Fourier, se obține o imagine cu valori numere complexe
  2863. Mat fourier;
  2864. centering_transform(srcf);
  2865. dft(srcf, fourier, DFT_COMPLEX_OUTPUT);
  2866. //divizare în două canale: partea reală și partea imaginară
  2867. Mat channels[] = { Mat::zeros(src.size(), CV_32F), Mat::zeros(src.size(), CV_32F) };
  2868. split(fourier, channels); // channels[0] = Re(DFT(I)), channels[1] = Im(DFT(I))
  2869. //calcularea magnitudinii și fazei în imaginile mag, respectiv phi, cu elemente de tip float
  2870. Mat mag, phi;
  2871. magnitude(channels[0], channels[1], mag);
  2872. phase(channels[0], channels[1], phi);
  2873. //aici afișați imaginile cu fazele și magnitudinile
  2874.  
  2875. Mat lmag = mag.clone();
  2876. for (int y = 0; y < lmag.rows; y++)
  2877. for (int x = 0; x < lmag.cols; x++)
  2878. lmag.at<float>(y, x) = log(lmag.at<float>(y, x) + 1);
  2879.  
  2880. Mat magu, phase;
  2881. normalize(lmag, magu, 0, 255, NORM_MINMAX, CV_8UC1);
  2882. normalize(phi, phase, 0, 255, NORM_MINMAX, CV_8UC1);
  2883. imshow("Mag", magu);
  2884. imshow("Pahse", phase);
  2885. waitKey(10);
  2886.  
  2887. //aici inserați operații de filtrare aplicate pe coeficienții Fourier
  2888. /*for (int y = 0; y < lmag.rows; y++)
  2889. for (int x = 0; x < lmag.cols; x++)
  2890. {
  2891. int dy = y - lmag.rows/2;
  2892. int dx = x - lmag.cols/2;
  2893. if (sqrt(dx*dx + dy * dy) > 20)
  2894. mag.at<float>(y, x) = 0.0f;
  2895. }*/
  2896.  
  2897. for (int y = 0; y < lmag.rows; y++)
  2898. for (int x = 0; x < lmag.cols; x++)
  2899. {
  2900. int dy = y - lmag.rows / 2;
  2901. int dx = x - lmag.cols / 2;
  2902. if (sqrt(dx*dx + dy * dy) > 20)
  2903. mag.at<float>(y, x) = 0.0f;
  2904. }
  2905.  
  2906. //memorați partea reală în channels[0] și partea imaginară în channels[1]
  2907. for (int y = 0; y < lmag.rows; y++)
  2908. for (int x = 0; x < lmag.cols; x++)
  2909. {
  2910. channels[0].at<float>(y, x) = mag.at<float>(y, x) * cos(phi.at<float>(y, x));
  2911. channels[1].at<float>(y, x) = mag.at<float>(y, x) * sin(phi.at<float>(y, x));
  2912. }
  2913. //aplicarea transformatei Fourier inversă și punerea rezultatului în dstf
  2914. Mat dst, dstf;
  2915. merge(channels, 2, fourier);
  2916. dft(fourier, dstf, DFT_INVERSE | DFT_REAL_OUTPUT | DFT_SCALE);
  2917. //transformarea de centrare inversă
  2918. centering_transform(dstf);
  2919. //normalizarea rezultatului în imaginea destinație
  2920. normalize(dstf, dst, 0, 255, NORM_MINMAX, CV_8UC1);
  2921. return dst;
  2922. }
  2923.  
  2924. void frequencyFilters()
  2925. {
  2926. char fname[MAX_PATH];
  2927. while (openFileDlg(fname))
  2928. {
  2929. Mat src;
  2930. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  2931.  
  2932. imshow("Original", src);
  2933.  
  2934. int height = src.rows;
  2935. int width = src.cols;
  2936.  
  2937. Mat res = generic_frequency_domain_filter(src);
  2938.  
  2939. imshow("Fourier Reconstr", res);
  2940. waitKey(10);
  2941.  
  2942.  
  2943. waitKey();
  2944. destroyAllWindows();
  2945. }
  2946. }
  2947.  
  2948. Mat variance(Mat image, int window_size)
  2949. {
  2950.  
  2951. int width = image.cols;
  2952. int height = image.rows;
  2953.  
  2954. Mat res = Mat::zeros(height, width, CV_8UC1);
  2955.  
  2956. for(int y = 0; y < height - window_size; y++)
  2957. for (int x = 0; x < width - window_size; x++)
  2958. {
  2959. int mean = 0;
  2960. for (int wy = 0; wy < window_size; wy++)
  2961. for (int wx = 0; wx < window_size; wx++)
  2962. {
  2963. int nx = x + wx;
  2964. int ny = y + wy;
  2965.  
  2966. mean += image.at<uchar>(ny, nx);
  2967. }
  2968. mean /= window_size * window_size;
  2969.  
  2970. int var = 0;
  2971. for (int wy = 0; wy < window_size; wy++)
  2972. for (int wx = 0; wx < window_size; wx++)
  2973. {
  2974. int nx = x + wx;
  2975. int ny = y + wy;
  2976.  
  2977.  
  2978.  
  2979. var += abs(image.at<uchar>(ny, nx) - mean);
  2980. }
  2981.  
  2982. var /= window_size * window_size;
  2983. res.at<uchar>(y + window_size / 2, x + window_size / 2) = var;
  2984. }
  2985.  
  2986. return res;
  2987. }
  2988.  
  2989. uchar meanI(Mat image)
  2990. {
  2991. int width = image.cols;
  2992. int height = image.rows;
  2993.  
  2994. int mean = 0;
  2995. for (int y = 0; y < height; y++)
  2996. for (int x = 0; x < width; x++)
  2997. {
  2998. mean += image.at<uchar>(y, x);
  2999. }
  3000. mean /= width * height;
  3001. return mean;
  3002. }
  3003.  
  3004. Mat varianceDistance(Mat image, Mat filter, int filterMean)
  3005. {
  3006. int width = image.cols;
  3007. int height = image.rows;
  3008.  
  3009. int fheight = filter.rows;
  3010. int fwidth = filter.cols;
  3011. Mat res = Mat::zeros(height, width, CV_8UC1);
  3012.  
  3013. for (int y = -fheight/2; y < height; y++)
  3014. for (int x = -fwidth/2; x < width; x++)
  3015. {
  3016. if (y + fheight / 2 >= height || x + fwidth / 2 >= width) continue;
  3017. int mean = 0;
  3018. for (int wy = 0; wy < fheight; wy++)
  3019. for (int wx = 0; wx < fwidth; wx++)
  3020. {
  3021. int nx = x + wx;
  3022. int ny = y + wy;
  3023. if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
  3024.  
  3025. mean += image.at<uchar>(ny, nx);
  3026. }
  3027. mean /= fwidth * fheight;
  3028.  
  3029. int var = 0;
  3030. for (int wy = 0; wy < fheight; wy++)
  3031. for (int wx = 0; wx < fwidth; wx++)
  3032. {
  3033. int nx = x + wx;
  3034. int ny = y + wy;
  3035.  
  3036. if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
  3037.  
  3038. int delta = (image.at<uchar>(ny, nx) - mean) - (filter.at<uchar>(wy, wx) - filterMean);
  3039. var += delta * delta;
  3040. }
  3041.  
  3042. var /= fwidth * fheight;
  3043. var = sqrt(var);
  3044. res.at<uchar>(y + fheight / 2, x + fwidth / 2) = var;
  3045. }
  3046. return res;
  3047. }
  3048.  
  3049. Mat filterPeaks(Mat image)
  3050. {
  3051. Mat res = image.clone();
  3052. int width = image.cols;
  3053. int height = image.rows;
  3054. for(int y = 0; y < height; y++)
  3055. for (int x = 0; x < width; x++)
  3056. {
  3057. auto ns = getNeighbours(x, y, width, height);
  3058. for (auto n : ns)
  3059. {
  3060. if (image.at<uchar>(n.y, n.x) <= image.at<uchar>(y, x))
  3061. res.at<uchar>(n.y, n.x) = 0;
  3062. }
  3063. }
  3064. return res;
  3065. }
  3066.  
  3067. int TopPercThreshold(Mat img, int low, int high, double topPercent)
  3068. {
  3069. int height = img.rows;
  3070. int width = img.cols;
  3071.  
  3072. int hist[256] = { 0 };
  3073. int count = 0;
  3074. for (int y = 0; y < height; y++)
  3075. for (int x = 0; x < width; x++)
  3076. {
  3077. if (img.at<uchar>(y, x) >= low && img.at<uchar>(y, x) <= high)
  3078. hist[img.at<uchar>(y, x)]++, count++;
  3079. }
  3080.  
  3081. int top = (1.0-topPercent) * count;
  3082. int thresh = 256;
  3083.  
  3084. while(count > top)
  3085. count -= hist[--thresh];
  3086.  
  3087. return thresh;
  3088.  
  3089. }
  3090.  
  3091. Mat cutBelow(Mat img, int thresh)
  3092. {
  3093. Mat res = img.clone();
  3094.  
  3095. int height = img.rows;
  3096. int width = img.cols;
  3097.  
  3098. for (int y = 0; y < height; y++)
  3099. for (int x = 0; x < width; x++)
  3100. if (img.at<uchar>(y, x) < thresh)
  3101. res.at<uchar>(y, x) = 0;
  3102. return res;
  3103. }
  3104.  
  3105. /*regular grid*/
  3106. vector<Mat> extractFeatures(Mat image)
  3107. {
  3108. int width = image.cols;
  3109. int height = image.rows;
  3110. /*96x96 / 12 = 8x8 features; 8 = ~8% * 96*/
  3111. int divisionFactor = 8;
  3112. int featureWidth = width / divisionFactor;
  3113. int featureHeight = height / divisionFactor;
  3114. vector<Mat> features;
  3115.  
  3116. Mat var = variance(image, 10);
  3117. Mat filtered_var = filterPeaks(var);
  3118.  
  3119. Mat var3 = variance(image, 3);
  3120. Mat filtered_var3 = filterPeaks(var3);
  3121.  
  3122. int topThresh = TopPercThreshold(filtered_var3, 1, 255, 0.2);
  3123.  
  3124. filtered_var3 = cutBelow(filtered_var3, topThresh);
  3125. Mat threshvar3 = cutBelow(var3, topThresh);
  3126.  
  3127. for(int y = 0; y < height; y++)
  3128. for(int x = 0; x < width; x++)
  3129. {
  3130. if(filtered_var3.at<uchar>(y,x) > 0)
  3131. {
  3132. int xmin = x - 1 , xmax = x + 1;
  3133. int ymin = y - 1, ymax = y + 1;
  3134. queue<Point2i> Q;
  3135. Q.push(Point2i(x, y));
  3136.  
  3137. while (!Q.empty() && ymax - ymin <= 13 && xmax - xmin <= 13)
  3138. {
  3139. Point2i curr = Q.front();
  3140. Q.pop();
  3141.  
  3142. threshvar3.at<uchar>(curr.y, curr.x) = 0;
  3143.  
  3144. auto ns = getNeighbours(curr.x, curr.y, width, height);
  3145. for (auto n : ns)
  3146. {
  3147. if (threshvar3.at<uchar>(n.y, n.x) > 0)
  3148. {
  3149. Q.push(n);
  3150. if (n.x > xmax) xmax = n.x;
  3151. if (n.x < xmin) xmin = n.x;
  3152. if (n.y > ymax) ymax = n.y;
  3153. if (n.y < ymin) ymin = n.y;
  3154. }
  3155. }
  3156. }
  3157.  
  3158. if (ymax - ymin > 13)
  3159. ymin = y - 6, ymax = y + 6;
  3160. if (xmax - xmin > 13)
  3161. xmin = x - 6, xmax = x + 6;
  3162.  
  3163. if (xmin < 0) xmin = 0;
  3164. if (xmax >= width) xmax = width - 1;
  3165. if (ymin < 0) ymin = 0;
  3166. if (ymax >= height) ymax = height - 1;
  3167.  
  3168. //Clear region with black
  3169. for (int ty = ymin; ty <= ymax; ty++)
  3170. for (int tx = xmin; tx <= xmax; tx++)
  3171. threshvar3.at<uchar>(ty, tx) = 0, filtered_var3.at<uchar>(ty, tx) = 0;
  3172.  
  3173. //Mat last = image(Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1));
  3174. auto r = Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
  3175. features.push_back(image(r));
  3176. }
  3177. }
  3178. return features;
  3179.  
  3180. }
  3181.  
  3182. vector<string> GetDirectoryFiles(const string& path) {
  3183. vector<string> files;
  3184. for (const auto& entry : filesystem::directory_iterator(path))
  3185. {
  3186. cout << entry.path() << endl;
  3187. files.push_back(entry.path().string());
  3188. }
  3189. return files;
  3190. }
  3191.  
  3192. void preProcessImages()
  3193. {
  3194. vector<string> files = GetDirectoryFiles(".\\Images\\data\\2");
  3195. cout << "Prerocessing files.." << endl;
  3196.  
  3197. vector<Mat> all_features;
  3198.  
  3199. for each (string s in files)
  3200. {
  3201. Mat image = imread(s.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
  3202. vector<Mat> features = extractFeatures(image);
  3203. all_features.insert(all_features.end(), features.begin(), features.end());
  3204.  
  3205. for (auto feature : features)
  3206. {
  3207. uchar mean = meanI(feature);
  3208. Mat res = varianceDistance(image, feature, mean);
  3209. Mat conv_res = convolveImg(image, feature);
  3210. cout << res;
  3211. cout << conv_res;
  3212. }
  3213. }
  3214.  
  3215. cout << "Features gathered: " << all_features.size() << endl;
  3216.  
  3217. vector<Mat> trimmed_features;
  3218. int count_convolutions = 0;
  3219. for(int i = 0; i < all_features.size(); i++)
  3220. {
  3221. bool ok = true;
  3222. for (int j = 0; j < all_features.size(); j++)
  3223. {
  3224. if (i == j)
  3225. continue;
  3226.  
  3227. count_convolutions++;
  3228. if (count_convolutions % 1000000 == 0)
  3229. cout << count_convolutions << endl;;
  3230.  
  3231. int conv_total = convolveImgIP(all_features[i], all_features[j]);
  3232. if (conv_total < 10)
  3233. {
  3234. /*
  3235. Mat conv_res = convolveImg(all_features[i], all_features[j]);
  3236. cout << conv_total << " ";
  3237. cout << conv_res.size() << endl;
  3238. */
  3239. ok = false;
  3240. }
  3241. }
  3242. if (ok) trimmed_features.push_back(all_features[i]);
  3243. }
  3244.  
  3245. cout << "Kept " << trimmed_features.size() << "features" <<endl;
  3246.  
  3247. for each (string s in files)
  3248. {
  3249. Mat image = imread(s.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
  3250. for each (Mat feature in trimmed_features) {
  3251. Mat conv = convolveImg(image, feature);
  3252. cout << "conv";
  3253. }
  3254.  
  3255. }
  3256.  
  3257. cout << "All images have been translated to features"<< endl;
  3258.  
  3259. system("pause>nul");
  3260. }
  3261.  
  3262. Mat InformationDesity(Mat img)
  3263. {
  3264. Mat laplaceFilter = Mat(3, 3, CV_16SC1);
  3265. for (int y = 0; y < laplaceFilter.rows; y++)
  3266. for (int x = 0; x < laplaceFilter.cols; x++)
  3267. laplaceFilter.at<short>(y, x) = -1;
  3268.  
  3269. laplaceFilter.at<short>(laplaceFilter.rows / 2, laplaceFilter.cols / 2) =
  3270. laplaceFilter.rows * laplaceFilter.cols - 1;
  3271.  
  3272. Mat lowPass = img.clone();
  3273. convolve(lowPass, img, laplaceFilter,false,true);
  3274.  
  3275. return lowPass;
  3276.  
  3277. }
  3278.  
  3279. void testInfoDensity()
  3280. {
  3281. char fname[MAX_PATH];
  3282. while (openFileDlg(fname))
  3283. {
  3284. Mat src;
  3285. src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
  3286.  
  3287. imshow("Original", src);
  3288.  
  3289. int height = src.rows;
  3290. int width = src.cols;
  3291.  
  3292. Mat res = InformationDesity(src);
  3293.  
  3294. imshow("Info Desity", res);
  3295. waitKey(10);
  3296.  
  3297.  
  3298. waitKey();
  3299. destroyAllWindows();
  3300. }
  3301. }
  3302.  
  3303. int main()
  3304. {
  3305. preProcessImages();
  3306. /*Point2i currentPoint;
  3307. Point2i neighbourPoint;
  3308. int dir;
  3309. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10, 7);
  3310. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3311. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3312. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3313. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3314. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3315. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3316. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
  3317. nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);*/
  3318.  
  3319. int op;
  3320. do
  3321. {
  3322. system("cls");
  3323. destroyAllWindows();
  3324. printf("Menu:\n");
  3325. printf(" 1 - Open image\n");
  3326. printf(" 2 - Open BMP images from folder\n");
  3327. printf(" 3 - Image negative - diblook style\n");
  3328. printf(" 4 - BGR->HSV\n");
  3329. printf(" 5 - Resize image\n");
  3330. printf(" 6 - Canny edge detection\n");
  3331. printf(" 7 - Edges in a video sequence\n");
  3332. printf(" 8 - Snap frame from live video\n");
  3333. printf(" 9 - Mouse callback demo\n");
  3334. printf(" 10 - Add gray\n");
  3335. printf(" 11 - Mult gray\n");
  3336. printf(" 12 - Flag\n");
  3337. printf(" 13 - Inversa Matrice 3x3\n");
  3338. printf(" 14 - RGB to 3 gray\n");
  3339. printf(" 15 - RGB to 1 gray\n");
  3340. printf(" 16 - RGB ro H,S,V\n");
  3341. printf(" 17 - testam negative_image()\n");
  3342. printf(" 18 - testThreshold\n");
  3343. printf(" 19 - IsInside\n");
  3344. printf(" 20 - L3 Hist 1-4\n");
  3345. printf(" 21 - L3 Hist Bins 5-6\n");
  3346. printf(" 22 - L3 Hue Reduce 7\n");
  3347. printf(" 23 - L3 Hist Bins 6\n");
  3348. printf(" 24 - L4 Process Object\n");
  3349. printf(" 25 - Label Objects BFS\n");
  3350. printf(" 26 - Label Objects 2 steps\n");
  3351. printf(" 27 - Find Border\n");
  3352. printf(" 28 - Reconstruct Border\n");
  3353. printf(" 29 - Erode Dilate\n");
  3354. printf(" 30 - Fill Ero\n");
  3355. printf(" 31 - Med, std dev, cfdp\n");
  3356. printf(" 32 - Auto Binarize\n");
  3357. printf(" 33 - Photoshop 101\n");
  3358. printf(" 34 - Equalize Histogram\n");
  3359. printf(" 35 - Convolutions\n");
  3360. printf(" 36 - Fourier\n");
  3361. printf(" 0 - Exit\n\n");
  3362. printf("Option: ");
  3363. scanf("%d",&op);
  3364. switch (op)
  3365. {
  3366. case 1:
  3367. testOpenImage();
  3368. break;
  3369. case 2:
  3370. testOpenImagesFld();
  3371. break;
  3372. case 3:
  3373. testParcurgereSimplaDiblookStyle(); //diblook style
  3374. break;
  3375. case 4:
  3376. //testColor2Gray();
  3377. testBGR2HSV();
  3378. break;
  3379. case 5:
  3380. testResize();
  3381. break;
  3382. case 6:
  3383. testCanny();
  3384. break;
  3385. case 7:
  3386. testVideoSequence();
  3387. break;
  3388. case 8:
  3389. testSnap();
  3390. break;
  3391. case 9:
  3392. testMouseClick();
  3393. break;
  3394. case 10:
  3395. testNegativeImageP();
  3396. break;
  3397. case 11:
  3398. testNegativeImageM();
  3399. break;
  3400. case 12:
  3401. test4Flag();
  3402. break;
  3403. case 13:
  3404. testInvMat3f();
  3405. break;
  3406. case 14:
  3407. testRGBComp();
  3408. break;
  3409. case 15:
  3410. testRGBGray();
  3411. break;
  3412. case 16:
  3413. testRGBHSV();
  3414. break;
  3415. case 17:
  3416. negative_image();
  3417. break;
  3418. case 18:
  3419. testThreshold();
  3420. break;
  3421. case 19:
  3422. testIsInside();
  3423. break;
  3424. case 20:
  3425. testL3Hist14();
  3426. break;
  3427. case 21:
  3428. testL3Bins56();
  3429. break;
  3430. case 22:
  3431. testL3Reduce7();
  3432. break;
  3433. case 23:
  3434. floyd_steinberg_dithering();
  3435. break;
  3436. case 24:
  3437. processObjects();
  3438. break;
  3439. case 25:
  3440. labelObjects();
  3441. break;
  3442. case 26:
  3443. labelObjects2Steps();
  3444. break;
  3445. case 27:
  3446. findBorder();
  3447. break;
  3448. case 28:
  3449. reconstruct();
  3450. break;
  3451. case 29:
  3452. EroDil();
  3453. break;
  3454. case 30:
  3455. FillEro();
  3456. break;
  3457. case 31:
  3458. imgStats();
  3459. break;
  3460. case 32:
  3461. autoBinarizeBimodal();
  3462. break;
  3463. case 33:
  3464. photoshop101();
  3465. break;
  3466. case 34:
  3467. equalizeHist();
  3468. break;
  3469. case 35:
  3470. lowHighPass();
  3471. break;
  3472. case 36:
  3473. frequencyFilters();
  3474. break;
  3475. case 37:
  3476. testInfoDensity();
  3477. break;
  3478. }
  3479. }while (op!=0);
  3480. return 0;
  3481. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement