Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // OpenCVApplication.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include "common.h"
- #include <random>
- #include <filesystem>
- using namespace std;
- void testOpenImage()
- {
- char fname[MAX_PATH];
- while(openFileDlg(fname))
- {
- Mat src;
- src = imread(fname);
- imshow("image",src);
- waitKey();
- }
- }
- void testOpenImagesFld()
- {
- char folderName[MAX_PATH];
- if (openFolderDlg(folderName)==0)
- return;
- char fname[MAX_PATH];
- FileGetter fg(folderName,"bmp");
- while(fg.getNextAbsFile(fname))
- {
- Mat src;
- src = imread(fname);
- imshow(fg.getFoundFileName(),src);
- if (waitKey()==27) //ESC pressed
- break;
- }
- }
- void testImageOpenAndSave()
- {
- Mat src, dst;
- src = imread("Images/Lena_24bits.bmp", CV_LOAD_IMAGE_COLOR); // Read the image
- if (!src.data) // Check for invalid input
- {
- printf("Could not open or find the image\n");
- return;
- }
- // Get the image resolution
- Size src_size = Size(src.cols, src.rows);
- // Display window
- const char* WIN_SRC = "Src"; //window for the source image
- namedWindow(WIN_SRC, CV_WINDOW_AUTOSIZE);
- cvMoveWindow(WIN_SRC, 0, 0);
- const char* WIN_DST = "Dst"; //window for the destination (processed) image
- namedWindow(WIN_DST, CV_WINDOW_AUTOSIZE);
- cvMoveWindow(WIN_DST, src_size.width + 10, 0);
- cvtColor(src, dst, CV_BGR2GRAY); //converts the source image to a grayscale one
- imwrite("Images/Lena_24bits_gray.bmp", dst); //writes the destination to file
- imshow(WIN_SRC, src);
- imshow(WIN_DST, dst);
- printf("Press any key to continue ...\n");
- waitKey(0);
- }
- void negative_image() {
- Mat img = imread("Images/cameraman.bmp",
- CV_LOAD_IMAGE_GRAYSCALE);
- for (int i = 0; i<img.rows; i++) {
- for (int j = 0; j<img.cols; j++) {
- img.at<uchar>(i, j) = 255 - img.at<uchar>(i, j);
- }
- }
- imshow("negative image", img);
- waitKey(0);
- }
- void testNegativeImage()
- {
- char fname[MAX_PATH];
- while(openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname,CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- Mat dst = Mat(height,width,CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i=0; i<height; i++)
- {
- for (int j=0; j<width; j++)
- {
- uchar val = src.at<uchar>(i,j);
- uchar neg = 255 - val;
- dst.at<uchar>(i,j) = neg;
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image",src);
- imshow("negative image",dst);
- waitKey();
- }
- }
- void testNegativeImageP()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- Mat dst = Mat(height, width, CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- uchar val = src.at<uchar>(i, j);
- int neg = val + 255;
- neg = neg > 255 ? 255 : neg;
- neg = neg < 0 ? 0 : neg;
- dst.at<uchar>(i, j) = neg;
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image", src);
- imshow("added gray image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- void testNegativeImageM()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- Mat dst = Mat(height, width, CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- uchar val = src.at<uchar>(i, j);
- int neg = (int)(val*1.50);
- neg = neg > 255 ? 255 : neg;
- neg = neg < 0 ? 0 : neg;
- dst.at<uchar>(i, j) = (uchar)neg;
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image", src);
- imshow("multiplied gray image", dst);
- imwrite("D:\\Projects\\Lab\\PI\\OpenCVApplication-VS2017_OCV340_basic\\Images\\imagine_salvata.bmp", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- void test4Flag()
- {
- Vec3b alb = Vec3b(255, 255, 255);//bgr
- Vec3b rosu = Vec3b(0, 0, 255);
- Vec3b verde = Vec3b(0, 255, 0);
- Vec3b galben = Vec3b(0, 255, 255);
- char fname[MAX_PATH];
- //while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- int height = 256;
- int width = 256;
- Mat dst = Mat(height, width, CV_8UC3);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- if (i < 128 && j < 128)
- dst.at<Vec3b>(i, j) = alb;
- else if (i > 128 && j < 128)
- dst.at<Vec3b>(i, j) = rosu;
- else if (i < 128 && j > 128)
- dst.at<Vec3b>(i, j) = verde;
- else
- dst.at<Vec3b>(i, j) = galben;
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("flag", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- void testInvMat3f()
- {
- int height = 3;
- int width = 3;
- float vals[9] = { 3, 0, 0, 0, 3, 0, 0, 0, 3 };
- Mat dst = Mat(width, height, CV_32FC1, vals);
- cout << "Input image:\n";
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- //dst.at<float>(i, j) = 0.7f;
- cout << dst.at<float>(i, j) << " ";
- }
- cout << endl;
- }
- cout << endl;
- dst= dst.inv();
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- cout << dst.at<float>(i, j) << " ";
- }
- cout << endl;
- }
- system("pause >nul");
- }
- void testParcurgereSimplaDiblookStyle()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- Mat dst = src.clone();
- double t = (double)getTickCount(); // Get the current time [s]
- // the fastest approach using the �diblook style�
- uchar *lpSrc = src.data;
- uchar *lpDst = dst.data;
- int w = (int) src.step; // no dword alignment is done !!!
- for (int i = 0; i<height; i++)
- for (int j = 0; j < width; j++) {
- uchar val = lpSrc[i*w + j];
- lpDst[i*w + j] = 255 - val;
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image",src);
- imshow("negative image",dst);
- waitKey();
- }
- }
- void testColor2Gray()
- {
- char fname[MAX_PATH];
- while(openFileDlg(fname))
- {
- Mat src = imread(fname);
- int height = src.rows;
- int width = src.cols;
- Mat dst = Mat(height,width,CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine RGB 24 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i=0; i<height; i++)
- {
- for (int j=0; j<width; j++)
- {
- Vec3b v3 = src.at<Vec3b>(i,j);
- uchar b = v3[0];
- uchar g = v3[1];
- uchar r = v3[2];
- dst.at<uchar>(i,j) = (r+g+b)/3;
- }
- }
- imshow("input image",src);
- imshow("gray image",dst);
- waitKey();
- }
- }
- void testRGBComp()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
- int height = src.rows;
- int width = src.cols;
- Mat dstr = Mat(height, width, CV_8UC1);
- Mat dstg = Mat(height, width, CV_8UC1);
- Mat dstb = Mat(height, width, CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- Vec3b val = src.at<Vec3b>(i, j);
- dstr.at<uchar>(i, j) = val[2];
- dstg.at<uchar>(i, j) = val[1];
- dstb.at<uchar>(i, j) = val[0];
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image", src);
- imshow("b image", dstr);
- imshow("g image", dstg);
- imshow("r image", dstb);
- waitKey();
- destroyAllWindows();
- }
- }
- float maxf(float a, float b, float c)
- {
- if (a > b)
- if (a > c)
- return a;
- else
- return c;
- else
- if (b > c)
- return b;
- else
- return c;
- }
- float minf(float a, float b, float c)
- {
- if (a < b)
- if (a < c)
- return a;
- else
- return c;
- else
- if (b < c)
- return b;
- else
- return c;
- }
- void testRGBHSV()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
- int height = src.rows;
- int width = src.cols;
- Mat dstr = Mat(height, width, CV_8UC1);
- Mat dstg = Mat(height, width, CV_8UC1);
- Mat dstb = Mat(height, width, CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- Vec3b val = src.at<Vec3b>(i, j);
- float r = val[2] / 255.0f;
- float g = val[1] / 255.0f;
- float b = val[0] / 255.0f;
- float ma = maxf(r, g, b);
- float mi = minf(r, g, b);
- float C = ma - mi;
- float V = ma;
- float S = 0.0;
- if (V > 0.0001f)
- S = C / V;
- float H = 0.0f;
- if(C > 0.001)
- {
- if (ma - r < 0.001f) H = 60 * (g - b) / C;
- if (ma - g < 0.001f) H = 120 * (b - r) / C;
- if (ma - b < 0.001f) H = 240 * (r - g) / C;
- }
- if (H < 0.0f)
- H += 360.0f;
- dstr.at<uchar>(i, j) = (uchar)(H * 255 / 360);
- dstg.at<uchar>(i, j) = (uchar)(S * 255);
- dstb.at<uchar>(i, j) = (uchar)(V * 255);
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image", src);
- imshow("h image", dstr);
- imshow("s image", dstg);
- imshow("v image", dstb);
- waitKey();
- destroyAllWindows();
- }
- }
- void testBGR2HSV()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src = imread(fname);
- int height = src.rows;
- int width = src.cols;
- // Componentele d eculoare ale modelului HSV
- Mat H = Mat(height, width, CV_8UC1);
- Mat S = Mat(height, width, CV_8UC1);
- Mat V = Mat(height, width, CV_8UC1);
- // definire pointeri la matricele (8 biti/pixeli) folosite la afisarea componentelor individuale H,S,V
- uchar* lpH = H.data;
- uchar* lpS = S.data;
- uchar* lpV = V.data;
- Mat hsvImg;
- cvtColor(src, hsvImg, CV_BGR2HSV);
- // definire pointer la matricea (24 biti/pixeli) a imaginii HSV
- uchar* hsvDataPtr = hsvImg.data;
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- int hi = i*width * 3 + j * 3;
- int gi = i*width + j;
- lpH[gi] = hsvDataPtr[hi] * 510 / 360; // lpH = 0 .. 255
- lpS[gi] = hsvDataPtr[hi + 1]; // lpS = 0 .. 255
- lpV[gi] = hsvDataPtr[hi + 2]; // lpV = 0 .. 255
- }
- }
- imshow("input image", src);
- imshow("H", H);
- imshow("S", S);
- imshow("V", V);
- waitKey();
- }
- }
- void testThreshold()
- {
- char fname[MAX_PATH];
- cout << "Da un numar bun: ";
- int thres;
- cin >> thres;
- thres = thres > 255 ? 255 : thres;
- thres = thres < 0 ? 0 : thres;
- while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- Mat dst = Mat(height, width, CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- uchar val = src.at<uchar>(i, j);
- if(val > thres)
- dst.at<uchar>(i, j) = (uchar)255;
- if(val < thres)
- dst.at<uchar>(i, j) = (uchar)0;
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image", src);
- imshow("multiplied gray image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- bool isInside(Mat m, int i, int j)
- {
- return i >= 0 && j >= 0 && j < m.cols && i < m.rows;
- }
- void testIsInside()
- {
- char fname[MAX_PATH];
- cout << "Dati numere consecutive i,j sau -1000 pentru stop\n";
- if (openFileDlg(fname))
- {
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int i, j;
- while (true)
- {
- cin >> i;
- if (i == -1000)
- return;
- cin >> j;
- if (j == -1000)
- return;
- cout << isInside(src, i, j) << endl;
- }
- }
- }
- void testRGBGray()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- double t = (double)getTickCount(); // Get the current time [s]
- Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
- int height = src.rows;
- int width = src.cols;
- Mat dst = Mat(height, width, CV_8UC1);
- // Asa se acceseaaza pixelii individuali pt. o imagine cu 8 biti/pixel
- // Varianta ineficienta (lenta)
- for (int i = 0; i<height; i++)
- {
- for (int j = 0; j<width; j++)
- {
- uchar r = src.at<Vec3b>(i, j)[2];
- uchar g = src.at<Vec3b>(i, j)[1];
- uchar b = src.at<Vec3b>(i, j)[0];
- dst.at<uchar>(i, j) = (uchar)((r+g+b)/3);
- }
- }
- // Get the current time again and compute the time difference [s]
- t = ((double)getTickCount() - t) / getTickFrequency();
- // Print (in the console window) the processing time in [ms]
- printf("Time = %.3f [ms]\n", t * 1000);
- imshow("input image", src);
- imshow("gray image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- /* LAB 3*/
- void showHistogram(const string& name, int* hist, const int hist_cols,
- const int hist_height) {
- Mat imgHist(hist_height, hist_cols, CV_8UC3, CV_RGB(255, 255, 255));
- // constructs a white image
- //computes histogram maximum
- int max_hist = 0;
- for (int i = 0; i<hist_cols; i++)
- if (hist[i] > max_hist)
- max_hist = hist[i];
- double scale = 1.0;
- scale = (double)hist_height / max_hist;
- int baseline = hist_height - 1;
- for (int x = 0; x < hist_cols; x++) {
- Point p1 = Point(x, baseline);
- Point p2 = Point(x, baseline - cvRound(hist[x] * scale));
- line(imgHist, p1, p2, CV_RGB(255, 0, 255)); // histogram bins
- // colored in magenta
- }
- imshow(name, imgHist);
- }
- void showHistogram(const string& name, double* hist, const int hist_cols,
- const int hist_height, const int vline1 = -1, const int vline2 = -1) {
- Mat imgHist(hist_height, hist_cols, CV_8UC3, CV_RGB(255, 255, 255));
- // constructs a white image
- //computes histogram maximum
- double max_hist = 0;
- for (int i = 0; i<hist_cols; i++)
- if (hist[i] > max_hist)
- max_hist = hist[i];
- double scale = 1.0;
- scale = hist_height / max_hist;
- double baseline = hist_height - 1;
- for (int x = 0; x < hist_cols; x++) {
- Point p1 = Point(x, baseline);
- Point p2 = Point(x, baseline - cvRound(hist[x] * scale));
- line(imgHist, p1, p2, CV_RGB(0, 0, 0)); // histogram bins
- // colored in magenta
- }
- if(vline1 != -1)
- {
- Point p1 = Point(vline1, baseline);
- Point p2 = Point(vline1, baseline - 255);
- line(imgHist, p1, p2, CV_RGB(0, 127, 255));
- }
- if (vline2 != -1)
- {
- Point p1 = Point(vline2, baseline);
- Point p2 = Point(vline2, baseline - 255);
- line(imgHist, p1, p2, CV_RGB(255, 127, 0));
- }
- imshow(name, imgHist);
- }
- int clamp(int v, int minv = 0, int maxv = 255)
- {
- if (v < minv) return minv;
- if (v > maxv) return maxv;
- return v;
- }
- void testL3Hist14()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- imshow("input image", src);
- waitKey(10);
- int* hist = (int*)malloc(sizeof(int) * 256);
- memset(hist, 0, sizeof(int) * 256);
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- hist[src.at<uchar>(i, j)]++;
- }
- }
- showHistogram("Standard", hist, 256, 200);
- double* histD = (double*)malloc(sizeof(double) * 256);
- double maxh = 0.0;
- for (int i = 0; i < 256; i++)
- if (hist[i] > maxh)
- maxh = hist[i];
- for (int i = 0; i < 256; i++)
- histD[i] = hist[i] / maxh;
- showHistogram("Normalized", histD, 256, 200);
- waitKey(10);
- int m = 0;
- while (true)
- {
- cout << "Dati m: ";
- cin >> m;
- if (m == -1) break;
- int divFact = 256 / m + 1;
- int* histR = (int*)malloc(sizeof(int) * m);
- memset(histR, 0, sizeof(int) * m);
- for (int i = 0; i < 256; i++)
- histR[i / divFact] += hist[i];
- showHistogram("Reduced", histR, m, 200);
- waitKey(0);
- free(histR);
- }
- free(hist);
- free(histD);
- waitKey();
- destroyAllWindows();
- }
- }
- int* calcHistogram(Mat imag)
- {
- int height = imag.rows;
- int width = imag.cols;
- int* hist = (int*)malloc(sizeof(int) * 256);
- memset(hist, 0, sizeof(int) * 256);
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- hist[imag.at<uchar>(i, j)]++;
- }
- }
- return hist;
- }
- /*
- * Normalised Values
- */
- double* calcNHistogram(Mat imag)
- {
- int height = imag.rows;
- int width = imag.cols;
- int* hist = calcHistogram(imag);
- double* histD = (double*)malloc(sizeof(double) * 256);
- double maxh = 0.0;
- for (int i = 0; i < 256; i++)
- if (hist[i] > maxh)
- maxh = hist[i];
- for (int i = 0; i < 256; i++)
- histD[i] = hist[i] / maxh;
- free(hist);
- return histD;
- }
- /*
- * Normalised sum
- */
- double* calcNHistogram(int* imagHist, int width, int height)
- {
- double* histD = (double*)malloc(sizeof(double) * 256);
- double maxh = width * height;
- /*for (int i = 0; i < 256; i++)
- if (imagHist[i] > maxh)
- maxh = imagHist[i];*/
- for (int i = 0; i < 256; i++)
- histD[i] = imagHist[i] / maxh;
- return histD;
- }
- /*Warning possible out of bounds error*/
- int* findPeaks(double* histD, int wh, double thresh, int* num_max = NULL )
- {
- int* maxime = (int*)malloc(sizeof(int) * 256);
- int lastmaxim = 1;
- maxime[0] = 0;
- for (int i = wh; i < 256 - wh; i++)
- {
- double local_sum = 0.0;
- double local_max = 0.0;
- for (int j = -wh; j <= wh; j++)
- {
- if (histD[i + j] > local_max)
- local_max = histD[i + j];
- local_sum += histD[i + j];
- }
- local_sum /= 2.0 * wh + 1.0;
- if (histD[i] > local_sum + thresh && histD[i] >= local_max)
- maxime[lastmaxim++] = i;
- }
- maxime[lastmaxim++] = 255;
- if(num_max != NULL)
- (*num_max) = lastmaxim;
- return maxime;
- }
- void testL3Bins56()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- imshow("input image", src);
- waitKey(10);
- int* hist = calcHistogram(src);
- double* histD = calcNHistogram(hist, width, height);
- showHistogram("Normalized", histD, 256, 200);
- waitKey(10);
- int wh = 5;
- double thresh = 0.0003;
- int lastmaxim;
- int* maxime = findPeaks(histD, 5, 0.0003, &lastmaxim);
- //maxime[lastmaxim++] = 255;
- Mat dst = Mat(height, width, CV_8UC1);
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- int cval = src.at<uchar>(i, j);
- int fval = 255;
- for(int k=1; k < lastmaxim; k++)
- if(cval <= maxime[k])
- {
- fval = cval - maxime[k-1] < maxime[k] - cval ? maxime[k-1] : maxime[k];
- break;
- }
- dst.at<uchar>(i, j) = fval;
- }
- }
- imshow("Reduced image", dst);
- waitKey(10);
- int* histRed = (int*)malloc(sizeof(int) * 256);
- memset(histRed, 0, sizeof(int) * 256);
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- histRed[dst.at<uchar>(i, j)]++;
- }
- }
- showHistogram("Reduced Hist", histRed, 256, 200);
- waitKey(10);
- //Floyd
- Mat dstCorr = Mat(height, width, CV_8UC1);
- const int WH = 5;
- const float TH = 0.0003;
- int roi_size = 2 * WH + 1;
- std::vector<int> maximum_values;
- for (int k = 0 + WH; k <= 255 - WH; k++)
- {
- float v = 0;
- bool greaterThan = true;
- for (int j = k - WH; j <= k + WH; j++)
- {
- v += histD[j];
- if (histD[k] < histD[j])
- greaterThan = false;
- }
- v /= roi_size;
- if (histD[k] > v + TH && greaterThan)
- maximum_values.push_back(k);
- }
- maximum_values.insert(maximum_values.begin(), 0);
- maximum_values.insert(maximum_values.end(), 255); //possible error
- /*Second Step*/
- for (int i = 1; i <= height - 2; i++)
- {
- for (int j = 1; j <= width - 2; j++)
- {
- int v = (int)dst.at<uchar>(i, j);
- int closest = 9999999;
- for (int l = 1; l < maximum_values.size(); l++)
- if (v <= maximum_values[l]) {
- closest = maximum_values[l] - v < v - maximum_values[l - 1] ? maximum_values[l] : maximum_values[l - 1];
- break;
- }
- dstCorr.at<uchar>(i, j) = closest;
- double error = v - closest;
- dstCorr.at<uchar>(i, j + 1) = min(255, max(0, dstCorr.at<uchar>(i, j + 1) + (int)(7 * error / 16)));
- dstCorr.at<uchar>(i + 1, j - 1) = min(255, max(0, dstCorr.at<uchar>(i + 1, j - 1) + (int)(3 * error / 16)));
- dstCorr.at<uchar>(i + 1, j) = min(255, max(0, dstCorr.at<uchar>(i + 1, j) + (int)(5 * error / 16)));
- dstCorr.at<uchar>(i + 1, j + 1) = min(255, max(0, dstCorr.at<uchar>(i + 1, j + 1) + (int)(error / 16)));
- }
- }
- imshow("Floyd Steinber Image", dstCorr);
- double* histN = calcNHistogram(dst);
- showHistogram("Floyd", histN, 256, 200);
- free(hist);
- free(histD);
- waitKey();
- destroyAllWindows();
- }
- }
- void floyd_steinberg_dithering()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src = imread(fname, CV_8UC1);
- Mat dst = src.clone();
- Mat dstpart = src.clone();
- int height = src.rows;
- int width = src.cols;
- const int WH = 5;
- const float TH = 0.0003;
- int roi_size = 2 * WH + 1;
- /*First Step*/
- int* hist = calcHistogram(src);
- showHistogram("Orig", hist, 256, 200);
- double* histogram_fdp = calcNHistogram(hist, width, height);
- std::vector<int> maximum_values;
- for (int k = 0 + WH; k <= 255 - WH; k++)
- {
- float v = 0;
- bool greaterThan = true;
- for (int j = k - WH; j <= k + WH; j++)
- {
- v += histogram_fdp[j];
- if (histogram_fdp[k] < histogram_fdp[j])
- greaterThan = false;
- }
- v /= roi_size;
- if (histogram_fdp[k] > v + TH && greaterThan)
- maximum_values.push_back(k);
- }
- maximum_values.insert(maximum_values.begin(), 0);
- maximum_values.insert(maximum_values.end(), 255);
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- int v = (int)dst.at<uchar>(i, j);
- int closest = 9999999;
- for (int l = 1; l < maximum_values.size(); l++)
- if (v <= maximum_values[l]) {
- closest = maximum_values[l] - v < v - maximum_values[l - 1] ? maximum_values[l] : maximum_values[l - 1];
- break;
- }
- dstpart.at<uchar>(i, j) = closest;
- }
- }
- double* histR = calcNHistogram(dstpart);
- showHistogram("Reduced", histR, 256, 200);
- imshow("Reduced Image", dstpart);
- /*Second Step*/
- for (int i = 1; i <= height - 2; i++)
- {
- for (int j = 1; j <= width - 2; j++)
- {
- int v = (int)dst.at<uchar>(i, j);
- int closest = 9999999;
- for (int l = 1; l < maximum_values.size(); l++)
- if (v <= maximum_values[l]) {
- closest = maximum_values[l] - v < v - maximum_values[l - 1] ? maximum_values[l] : maximum_values[l - 1];
- break;
- }
- dst.at<uchar>(i, j) = closest;
- double error = v - closest;
- dst.at<uchar>(i, j + 1) = min(255, max(0, dst.at<uchar>(i, j + 1) + (int)(7 * error / 16)));
- dst.at<uchar>(i + 1, j - 1) = min(255, max(0, dst.at<uchar>(i + 1, j - 1) + (int)(3 * error / 16)));
- dst.at<uchar>(i + 1, j) = min(255, max(0, dst.at<uchar>(i + 1, j) + (int)(5 * error / 16)));
- dst.at<uchar>(i + 1, j + 1) = min(255, max(0, dst.at<uchar>(i + 1, j + 1) + (int)(error / 16)));
- }
- }
- double* histN = calcNHistogram(dst);
- showHistogram("Floyd", histN, 256, 200);
- imshow("Floyd Steinber Image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- void testL3Reduce7()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
- int height = src.rows;
- int width = src.cols;
- Mat inter = Mat(height, width, CV_8UC3);
- cvtColor(src, inter, CV_BGR2HSV);
- Mat dst = Mat(height, width, CV_8UC3);
- imshow("input image", src);
- waitKey(10);
- int* hist = (int*)malloc(sizeof(int) * 256);
- memset(hist, 0, sizeof(int) * 256);
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- hist[inter.at<Vec3b>(i, j)[0]]++;
- }
- }
- double* histD = (double*)malloc(sizeof(double) * 256);
- double maxh = 0.0;
- for (int i = 0; i < 256; i++)
- if (hist[i] > maxh)
- maxh = hist[i];
- for (int i = 0; i < 256; i++)
- histD[i] = hist[i] / maxh;
- showHistogram("Normalized", histD, 256, 200);
- waitKey(10);
- int wh = 5;
- double thresh = 0.5;
- int maxime[256]; int lastmaxim = 1;
- maxime[0] = 0;
- for (int i = wh; i < 256 - wh; i++)
- {
- double local_sum = 0.0;
- for (int j = -wh; j <= wh; j++)
- {
- local_sum += histD[i + j];
- }
- local_sum /= 2 * wh + 1;
- if (histD[i] > local_sum + thresh)
- maxime[lastmaxim++] = i;
- }
- maxime[lastmaxim++] = 255;
- //maxime[lastmaxim++] = 255;
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < width; j++)
- {
- int cval = inter.at<Vec3b>(i, j)[0];
- int fval = 255;
- for (int k = 0; k < lastmaxim - 1; k++)
- if (cval >= maxime[k])
- fval = cval - maxime[k] < maxime[k + 1] - cval ? maxime[k] : maxime[k + 1];
- inter.at<Vec3b>(i, j)[0] = fval;
- }
- }
- cvtColor(inter, dst, CV_HSV2BGR);
- imshow("Converted image", dst);
- free(hist);
- free(histD);
- waitKey();
- destroyAllWindows();
- }
- }
- /* Other things*/
- void testResize()
- {
- char fname[MAX_PATH];
- while(openFileDlg(fname))
- {
- Mat src;
- src = imread(fname);
- Mat dst1,dst2;
- //without interpolation
- resizeImg(src,dst1,320,false);
- //with interpolation
- resizeImg(src,dst2,320,true);
- imshow("input image",src);
- imshow("resized image (without interpolation)",dst1);
- imshow("resized image (with interpolation)",dst2);
- waitKey();
- }
- }
- void testCanny()
- {
- char fname[MAX_PATH];
- while(openFileDlg(fname))
- {
- Mat src,dst,gauss;
- src = imread(fname,CV_LOAD_IMAGE_GRAYSCALE);
- double k = 0.4;
- int pH = 50;
- int pL = (int) k*pH;
- GaussianBlur(src, gauss, Size(5, 5), 0.8, 0.8);
- Canny(gauss,dst,pL,pH,3);
- imshow("input image",src);
- imshow("canny",dst);
- waitKey();
- }
- }
- void testVideoSequence()
- {
- VideoCapture cap("Videos/rubic.avi"); // off-line video from file
- //VideoCapture cap(0); // live video from web cam
- if (!cap.isOpened()) {
- printf("Cannot open video capture device.\n");
- waitKey(0);
- return;
- }
- Mat edges;
- Mat frame;
- char c;
- while (cap.read(frame))
- {
- Mat grayFrame;
- cvtColor(frame, grayFrame, CV_BGR2GRAY);
- Canny(grayFrame,edges,40,100,3);
- imshow("source", frame);
- imshow("gray", grayFrame);
- imshow("edges", edges);
- c = cvWaitKey(0); // waits a key press to advance to the next frame
- if (c == 27) {
- // press ESC to exit
- printf("ESC pressed - capture finished\n");
- break; //ESC pressed
- };
- }
- }
- void testSnap()
- {
- VideoCapture cap(0); // open the deafult camera (i.e. the built in web cam)
- if (!cap.isOpened()) // openenig the video device failed
- {
- printf("Cannot open video capture device.\n");
- return;
- }
- Mat frame;
- char numberStr[256];
- char fileName[256];
- // video resolution
- Size capS = Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH),
- (int)cap.get(CV_CAP_PROP_FRAME_HEIGHT));
- // Display window
- const char* WIN_SRC = "Src"; //window for the source frame
- namedWindow(WIN_SRC, CV_WINDOW_AUTOSIZE);
- cvMoveWindow(WIN_SRC, 0, 0);
- const char* WIN_DST = "Snapped"; //window for showing the snapped frame
- namedWindow(WIN_DST, CV_WINDOW_AUTOSIZE);
- cvMoveWindow(WIN_DST, capS.width + 10, 0);
- char c;
- int frameNum = -1;
- int frameCount = 0;
- for (;;)
- {
- cap >> frame; // get a new frame from camera
- if (frame.empty())
- {
- printf("End of the video file\n");
- break;
- }
- ++frameNum;
- imshow(WIN_SRC, frame);
- c = cvWaitKey(10); // waits a key press to advance to the next frame
- if (c == 27) {
- // press ESC to exit
- printf("ESC pressed - capture finished");
- break; //ESC pressed
- }
- if (c == 115){ //'s' pressed - snapp the image to a file
- frameCount++;
- fileName[0] = NULL;
- sprintf(numberStr, "%d", frameCount);
- strcat(fileName, "Images/A");
- strcat(fileName, numberStr);
- strcat(fileName, ".bmp");
- bool bSuccess = imwrite(fileName, frame);
- if (!bSuccess)
- {
- printf("Error writing the snapped image\n");
- }
- else
- imshow(WIN_DST, frame);
- }
- }
- }
- void MyCallBackFunc(int event, int x, int y, int flags, void* param)
- {
- //More examples: http://opencvexamples.blogspot.com/2014/01/detect-mouse-clicks-and-moves-on-image.html
- Mat* src = (Mat*)param;
- if (event == CV_EVENT_LBUTTONDOWN)
- {
- printf("Pos(x,y): %d,%d Color(RGB): %d,%d,%d\n",
- x, y,
- (int)(*src).at<Vec3b>(y, x)[2],
- (int)(*src).at<Vec3b>(y, x)[1],
- (int)(*src).at<Vec3b>(y, x)[0]);
- }
- }
- void testMouseClick()
- {
- Mat src;
- // Read image from file
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- src = imread(fname);
- //Create a window
- namedWindow("My Window", 1);
- //set the callback function for any mouse event
- setMouseCallback("My Window", MyCallBackFunc, &src);
- //show the image
- imshow("My Window", src);
- // Wait until user press some key
- waitKey(0);
- }
- }
- boolean isPerim(Mat imag, int x, int y, Vec3b bgCol)
- {
- int neigh[] = { -1,0,1 };
- for(int dy = 0; dy < 3; dy++)
- for(int dx = 0; dx < 3; dx++)
- {
- int nx = x + neigh[dx];
- int ny = y + neigh[dy];
- if (ny >= imag.rows || nx >= imag.cols || ny < 0 || nx < 0)
- continue;
- if (imag.at<Vec3b>(ny, nx) == bgCol)
- return true;
- }
- return false;
- }
- void processObjHandler(int event, int mx, int my, int flags, void* param)
- {
- if (event != EVENT_LBUTTONDOWN) return;
- Mat src = *(Mat*)param;
- Mat objOnly = Mat(src.rows, src.cols, CV_8UC3);
- Mat proiectii = Mat(src.rows, src.cols, CV_8UC3);
- int height = src.rows;
- int width = src.cols;
- int* pry = (int*)malloc(sizeof(int) * height);
- int* prx = (int*)malloc(sizeof(int) * width);
- memset(pry, 0, sizeof(int) * height);
- memset(prx, 0, sizeof(int) * width);
- Vec3b bgcol = src.at<Vec3b>(0, 0);
- Vec3b objcol = src.at<Vec3b>(my, mx);
- //std::vector<Point2i> points;
- //std::vector<Point2i> perimPoints;
- int area = 0;
- int perim = 0;
- long avgx = 0, avgy = 0;
- int minx = width;
- int miny = height;
- int maxx = 0;
- int maxy = 0;
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- if (src.at<Vec3b>(y, x) != objcol) continue;
- if (x > maxx) maxx = x;
- if (y > maxy) maxy = y;
- if (x < minx) minx = x;
- if (y < miny) miny = y;
- objOnly.at<Vec3b>(y, x) = objcol;
- //points.emplace_back(x, y);
- area++;
- avgx += x;
- avgy += y;
- if (isPerim(src, x, y, bgcol))
- {
- perim++;
- objOnly.at<Vec3b>(y, x) = Vec3b(0,0,0);
- //perimPoints.emplace_back(x, y);
- }
- pry[y]++;
- prx[x]++;
- }
- }
- avgx /= area;
- avgy /= area;
- int deviatie = 0;
- int devx = 0;
- int devy = 0;
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- if (src.at<Vec3b>(y, x) != objcol) continue;
- deviatie += (y - avgy) * (x - avgx);
- devx += (x - avgx) * (x - avgx);
- devy += (y - avgy) * (y - avgy);
- }
- }
- double angle = atan2(2.0*deviatie, devx - devy) / 2.0;
- for(double r = -40.0; r < 40.0; r += 1.0)
- {
- int cx = (int)(avgx + r * cos(angle));
- int cy = (int)(avgy + r * sin(angle));
- if (cy >= objOnly.rows || cx >= objOnly.cols || cy < 0 || cx < 0) continue;
- objOnly.at<Vec3b>(cy, cx) = Vec3b(200, 200, 50);
- }
- for (int x = 0; x < width; x++)
- for (int y = 0; y < height; y++)
- {
- proiectii.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
- }
- for(int y =0; y < height; y++)
- for(int x = 0; x < pry[y]; x++)
- {
- proiectii.at<Vec3b>(y, x) += Vec3b(255, 127, 0);
- }
- for (int x = 0; x < width; x++)
- for (int y = 0; y < prx[x]; y++)
- {
- proiectii.at<Vec3b>(y, x) += Vec3b(0, 127, 255);
- }
- /*Draw Center*/
- int neigh[] = { -1,0,1 };
- for (int dy = 0; dy < 3; dy++)
- for (int dx = 0; dx < 3; dx++)
- {
- int nx = avgx + neigh[dx];
- int ny = avgy + neigh[dy];
- if (ny >= objOnly.rows || nx >= objOnly.cols || ny < 0 || nx < 0)
- continue;
- objOnly.at<Vec3b>(ny, nx) = Vec3b(255, 255, 0);
- }
- double asprat = 1.0 * (maxx - minx) / (maxy - miny);
- double factsubt = 4.0 * PI * area / (perim * perim) ;
- cout << "Centru de greutate (x,y): " << avgx << ", " << avgy << endl;
- cout << "Arie: " << area << endl;
- cout << "Perimetru: " << perim << endl;
- cout << "Aspect Ratio: " << asprat << endl;
- cout << "Factor de subtiere: " << factsubt << endl;
- cout << "Unghi: " << angle * 180 / PI << endl;
- cout << endl;
- imshow("ObjOnly", objOnly);
- waitKey(10);
- imshow("Proiectii", proiectii);
- waitKey(10);
- }
- void processObjects()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_COLOR);
- imshow("Orig Image", src);
- setMouseCallback("Orig Image", processObjHandler, &src);
- waitKey();
- destroyAllWindows();
- }
- }
- /*
- * option values:
- * 4 - four neighbours
- * 8 - all neighbours
- * 81 - all neighbours withou center
- * -1 - previous neighbours
- * 1 - future neighbours
- */
- vector<Point2i> getNeighbours(int x, int y, int width, int height, int option = 81)
- {
- vector<Point2i> points;
- int neigh[] = { -1,0,1 };
- for (int dy = 0; dy < 3; dy++)
- for (int dx = 0; dx < 3; dx++)
- {
- int nx = x + neigh[dx];
- int ny = y + neigh[dy];
- if (nx < 0 || ny < 0 || nx >= width || ny>= height) continue;
- //if (dx == 1 && dy == 1) continue;
- if (option == 8)
- points.emplace_back(nx, ny);
- else if (option == 81 && dx != 1 && dy != 1)
- points.emplace_back(nx, ny);
- else if (option == 4 && (dx-1) * (dy-1) == 0)
- points.emplace_back(nx, ny);
- else if (option == -1 && (dy == 0 || dy == 1 && dx == 0))
- points.emplace_back(nx, ny);
- else if (option == 1 && !(dy == 0 || dy == 1 && dx == 0))
- points.emplace_back(nx, ny);
- }
- return points;
- }
- void labelObjects()
- {
- Vec3b manyColors[256];
- default_random_engine gen;
- uniform_int_distribution<int> d(0, 255);
- for (int i = 0; i < 256; i++)
- manyColors[i] = Vec3b(d(gen), d(gen), d(gen));
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src, dst, gauss;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- dst = Mat::zeros(cv::Size(width, height), CV_8UC3);
- int label = 0;
- Mat labels = Mat::zeros(cv::Size(width, height), CV_16SC1);
- for(int y = 0; y < height; y++)
- for(int x = 0; x < width; x++)
- {
- if (src.at<uchar>(y, x) == 0 && labels.at<short>(y, x) == 0)
- {
- label++;
- queue<Point2i>Q;
- dst.at<Vec3b>(y, x) = manyColors[label];
- Q.push(Point2i(x, y));
- labels.at<short>(y, x) = label;
- while(!Q.empty())
- {
- Point2i cp = Q.front();
- Q.pop();
- auto neighbours = getNeighbours(cp.x, cp.y, width, height);
- for (auto n : neighbours)
- {
- if (src.at<uchar>(n.y, n.x) == 0 && labels.at<short>(n.y, n.x) == 0)
- {
- Q.push(Point2i(n.x, n.y));
- dst.at<Vec3b>(n.y, n.x) = manyColors[label];
- labels.at<short>(n.y, n.x) = label;
- }
- }
- }
- }
- }
- imshow("input image", src);
- imshow("labeled image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- void labelObjects2Steps()
- {
- Vec3b manyColors[256];
- default_random_engine gen;
- uniform_int_distribution<int> d(0, 255);
- for (int i = 0; i < 256; i++)
- manyColors[i] = Vec3b(d(gen), d(gen), d(gen));
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src, dst, interm;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- dst = Mat::zeros(cv::Size(width, height), CV_8UC3);
- interm = Mat::zeros(cv::Size(width, height), CV_8UC3);
- int label = 0;
- Mat labels = Mat::zeros(cv::Size(width, height), CV_16SC1);
- vector<vector <int>> edges;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- if (src.at<uchar>(y, x) != 0 || labels.at<short>(y, x) != 0) continue;
- vector<int> L;
- auto neighbours = getNeighbours(x, y, width, height, -1);
- for (auto n : neighbours)
- {
- if (labels.at<short>(n.y, n.x) > 0)
- L.push_back(labels.at<short>(n.y, n.x));
- }
- if (L.size() == 0)
- {
- label++;
- labels.at<short>(y, x) = label;
- interm.at<Vec3b>(y, x) = manyColors[label];
- edges.resize(label + 1);
- }
- else
- {
- int minv = L[0];
- for (int i = 0; i < L.size(); i++)
- if (L[i] < minv)
- minv = L[i];
- labels.at<short>(y, x) = minv;
- interm.at<Vec3b>(y, x) = manyColors[minv];
- for (auto cl : L)
- if (cl != minv)
- {
- edges[minv].push_back(cl);
- edges[cl].push_back(minv);
- }
- }
- }
- int newlabel = 0;
- int newlabels[256];
- memset(newlabels, 0, 256 * sizeof(int));
- for(int i = 1; i <= label; i++)
- {
- if(newlabels[i] == 0)
- {
- newlabel++;
- queue<int> Q;
- newlabels[i] = newlabel;
- Q.push(i);
- while(!Q.empty())
- {
- auto head = Q.front();
- Q.pop();
- for (auto edge : edges[head])
- {
- if (newlabels[edge] == 0)
- {
- newlabels[edge] = newlabel;
- Q.push(edge);
- }
- }
- }
- }
- }
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- labels.at<short>(y, x) = newlabels[labels.at<short>(y, x)];
- dst.at<Vec3b>(y, x) = manyColors[labels.at<short>(y, x)];
- }
- imshow("input image", src);
- imshow("1st image", interm);
- imshow("labeled image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- bool isInside(int width, int height, Point2i p)
- {
- return p.x >= 0 && p.y >= 0 && p.x < width && p.y < height;
- }
- /*
- * option values:
- * 4 - four neighbours
- * 8 - all neighbours
- */
- bool nextNeigh(Point2i currentPoint, Point2i *neighbourPoint, int *dir, int option, int width, int height, int startingDir = -1)
- {
- static int lastDir = 0;
- if (startingDir != -1)
- {
- lastDir = startingDir;
- if (option == 4)
- lastDir = (lastDir + 3) % 4;
- if (option == 8)
- lastDir = lastDir % 2 ? (lastDir + 6) % 8 : (lastDir + 7) % 8;
- }
- int ndx[] = { 1,1,0,-1,-1,-1,0,1 };
- int ndy[] = { 0,1,1,1,0,-1,-1,-1 };
- if(option == 4)
- {
- *dir = lastDir;
- *neighbourPoint = Point2i(currentPoint.x + ndx[(*dir * 2) %8], currentPoint.y + ndy[(*dir * 2) % 8]*-1);
- lastDir = (lastDir + 1) % 4;
- return isInside(width, height, *neighbourPoint);
- }
- if (option == 8)
- {
- *dir = lastDir;
- *neighbourPoint = Point2i(currentPoint.x + ndx[*dir%8], currentPoint.y + ndy[*dir % 8] * -1);
- lastDir = (lastDir + 1) % 8;
- return isInside(width, height, *neighbourPoint);
- }
- return false;
- }
- void findBorder()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src, dst1, dst2;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- dst1 = Mat::zeros(cv::Size(width, height), CV_8UC3);
- dst2 = Mat::zeros(cv::Size(width, height), CV_8UC3);
- char bgCol = src.at<char>(0, 0);
- //copy image to output
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- if (src.at<char>(y, x) != bgCol)
- {
- dst1.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
- dst2.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
- }else
- {
- dst1.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
- dst2.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
- }
- }
- vector<Point2i> points;
- vector<int> directions;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- if (src.at<char>(y, x) != bgCol)
- {
- points.emplace_back(x, y);
- x = width;
- y = height;
- }
- int dir = 7;
- while(true)//cat timp nu s-a ajuns la inceput
- {
- Point2i currentPoint = points.back();
- Point2i neighbourPoint;
- bool inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 8, width, height, dir);
- do {
- if(inside)
- if (src.at<char>(neighbourPoint.y, neighbourPoint.x) != bgCol)
- {
- dst1.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[0] = 255;
- dst1.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[2] = 255;
- points.push_back(neighbourPoint);
- break;
- }
- inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 8, width, height);
- } while (true);//cat timp nu a fost gasit un vecin
- directions.push_back(dir);
- if (points.size() > 2)
- if (points[0] == points[points.size() - 2] && points[1] == points[points.size() - 1])
- break;
- }
- cout << "8 vecini: ";
- for (int i = 0; i < directions.size(); i++)
- cout << directions[i] << " ";
- cout << endl;
- cout << "derivate: ";
- for (int i = 1, cd = 0; i < directions.size(); i++)
- cout << (directions[i] - directions[i - 1] < 0 ? directions[i] - directions[i - 1] + 8 : directions[i] - directions[i - 1]) << " ";
- cout << endl;
- points.clear();
- directions.clear();
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- if (src.at<char>(y, x) != bgCol)
- {
- points.emplace_back(x, y);
- x = width;
- y = height;
- }
- dir = 0;
- while (true)//cat timp nu s-a ajuns la inceput
- {
- Point2i currentPoint = points.back();
- Point2i neighbourPoint;
- bool inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 4, width, height, dir);
- do {
- if (inside)
- if (src.at<char>(neighbourPoint.y, neighbourPoint.x) != bgCol)
- {
- dst2.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[2] = 255;
- dst2.at<Vec3b>(neighbourPoint.y, neighbourPoint.x)[0] = 255;
- points.push_back(neighbourPoint);
- break;
- }
- inside = nextNeigh(currentPoint, &neighbourPoint, &dir, 4, width, height);
- } while (true);//cat timp nu a fost gasit un vecin
- directions.push_back(dir);
- if (points.size() > 2)
- if (points[0] == points[points.size() - 2] && points[1] == points[points.size() - 1])
- break;
- }
- cout << "4 vecini: ";
- for (int i = 0; i < directions.size(); i++)
- cout << directions[i] << " ";
- cout << endl;
- cout << "derivate: ";
- for (int i = 1; i < directions.size(); i++)
- cout << (directions[i] - directions[i - 1] < 0 ? directions[i] - directions[i - 1] + 4 : directions[i] - directions[i - 1]) << " ";
- cout << endl;
- imshow("input image", src);
- imshow("cont4 image", dst2);
- imshow("cont8 image", dst1);
- waitKey();
- destroyAllWindows();
- }
- }
- void reconstruct()
- {
- int ndx[] = { 1,1,0,-1,-1,-1,0,1 };
- int ndy[] = { 0,1,1,1,0,-1,-1,-1 };
- ifstream inFile;
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- inFile.open("D:\\Projects\\Lab\\PI\\OpenCVApplication-VS2017_OCV340_basic\\Images\\l6\\reconstruct.txt");
- Mat src, dst, interm;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- dst = Mat::zeros(cv::Size(width, height), CV_8UC3);
- interm = Mat::zeros(cv::Size(width, height), CV_8UC3);
- int px, py;
- inFile >> py;
- inFile >> px;
- int n;
- inFile >> n;
- int dir = 7;
- for(int i = 0; i < n; i++)
- {
- int dDir;
- inFile >> dir;
- //dir = (dir + dDir) % 8;
- px += ndx[dir];
- py += ndy[dir];
- if(isInside(src,py,px))
- src.at<uchar>(height-py, px) = 255;
- }
- imshow("Reconstruction", src);
- //imshow("1st image", interm);
- //imshow("cont image", dst);
- waitKey();
- destroyAllWindows();
- }
- }
- void dilate(Mat img, int option = 8)
- {
- Mat tmp = img.clone();
- int height = tmp.rows;
- int width = tmp.cols;
- for(int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- auto neigh = getNeighbours(x, y, width, height, option);
- uchar maxc = 0;
- for (auto n : neigh)
- maxc = max(tmp.at<uchar>(n.y, n.x), maxc);
- img.at<uchar>(y, x) = maxc;
- }
- }
- void erode(Mat img, int option = 8)
- {
- Mat tmp = img.clone();
- int height = tmp.rows;
- int width = tmp.cols;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- auto neigh = getNeighbours(x, y, width, height, option);
- uchar minc = 255;
- for (auto n : neigh)
- minc = min(tmp.at<uchar>(n.y, n.x), minc);
- img.at<uchar>(y, x) = minc;
- }
- }
- void ed_open(Mat img, int option = 8)
- {
- erode(img, option);
- dilate(img, option);
- }
- void ed_close(Mat img, int option = 8)
- {
- dilate(img, option);
- erode(img, option);
- }
- void substract(Mat res, Mat a, Mat b)
- {
- if (a.rows != b.rows) return;
- if (a.cols != b.cols) return;
- int height = res.rows;
- int width = res.cols;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- res.at<uchar>(y, x) = max((int)a.at<uchar>(y, x) - (int)b.at<uchar>(y, x), 0);
- }
- void add(Mat res, Mat a, Mat b)
- {
- if (a.rows != b.rows) return;
- if (a.cols != b.cols) return;
- int height = res.rows;
- int width = res.cols;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- res.at<uchar>(y, x) = min((int)a.at<uchar>(y, x) + (int)b.at<uchar>(y, x), 255);
- }
- void invert(Mat res)
- {
- int height = res.rows;
- int width = res.cols;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- res.at<uchar>(y, x) = 255 -res.at<uchar>(y, x);
- }
- bool ed_cmp(Mat a, Mat b)
- {
- int height = a.rows;
- int width = a.cols;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- if (a.at<uchar>(y, x) != b.at<uchar>(y, x))
- return false;
- return true;
- }
- void EroDil()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src, dil14, dil18, diln8, ero14, ero18, eron4, eron8, open1, openn, close1, closen;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- int n;
- cin >> n;
- imshow("input image", src);
- dil14 = src.clone();
- dilate(dil14, 4);
- imshow("1xdil4 image", dil14);
- dil18 = src.clone();
- dilate(dil18, 8);
- imshow("1xdil8 image", dil18);
- diln8 = src.clone();
- for(int i =0; i < n; i++)
- dilate(diln8, 8);
- imshow("nxdil8 image", diln8);
- ero14 = src.clone();
- erode(ero14, 4);
- imshow("1xero4 image", ero14);
- ero18 = src.clone();
- erode(ero18, 8);
- imshow("1xero8 image", ero18);
- eron8 = src.clone();
- for (int i = 0; i < n; i++)
- erode(eron8, 8);
- imshow("nxero8 image", eron8);
- open1 = src.clone();
- ed_open(open1, 8);
- imshow("1xopen image", open1);
- openn = src.clone();
- for (int i = 0; i < n; i++)
- ed_open(openn, 8);
- imshow("nxopen image", openn);
- close1 = src.clone();
- ed_close(close1, 8);
- imshow("1xclose image", close1);
- closen = src.clone();
- for (int i = 0; i < n; i++)
- ed_close(closen, 8);
- imshow("nxclose image", closen);
- waitKey();
- destroyAllWindows();
- }
- }
- void fillObjHandler(int event, int mx, int my, int flags, void* param)
- {
- if (event != EVENT_LBUTTONDOWN) return;
- Mat src = *(Mat*)param;
- int height = src.rows;
- int width = src.cols;
- if (src.at<uchar>(my, mx) == 0) return;
- invert(src);
- Mat tmp = Mat::zeros(cv::Size(width, height), CV_8UC1);
- tmp.at<uchar>(my, mx) = 255;
- Mat prev = tmp.clone();
- while (true)
- {
- dilate(tmp);
- substract(tmp, tmp, src);
- if (ed_cmp(prev, tmp)) break;
- prev = tmp.clone();
- }
- add(src, tmp, src);
- invert(src);
- imshow("Contour Image", src);
- waitKey(10);
- }
- void FillEro()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src, cont;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- cont = src.clone();
- dilate(cont);
- substract(cont, cont, src);
- invert(cont);
- imshow("Orig Image", src);
- imshow("Contour Image", cont);
- setMouseCallback("Contour Image", fillObjHandler, &cont);
- waitKey();
- destroyAllWindows();
- }
- }
- void imgStats()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src, cont;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- cont = src.clone();
- int *hist = calcHistogram(src);
- double *phist = calcNHistogram(hist, src.cols, src.rows);
- int u = 0;
- for (int i = 0; i < 255; i++)
- u += i * hist[i];
- u /= width * height;
- cout << "Medie: " << u << endl;
- int stddev = 0;
- for (int i = 0; i < 255; i++)
- for(int j = 0; j < hist[i]; j++)
- stddev += (i - u)*(i - u);
- stddev /= width * height;
- stddev = sqrt(stddev);
- cout << "Deviate Standard: " << stddev << endl;
- showHistogram("PDF Orig", phist, 255, 200, u, u+stddev);
- int *chist = calcHistogram(src);
- for (int i = 1; i < 255; i++)
- chist[i] += chist[i - 1];
- showHistogram("CDF", chist, 255, 200);
- imshow("Orig Image", src);
- waitKey();
- destroyAllWindows();
- }
- }
- void autoBinarizeBimodal()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- int height = src.rows;
- int width = src.cols;
- int *hist = calcHistogram(src);
- double T = 127;
- double minh = 255;
- double maxh = 0;
- for(int i = 0; i < 255; i++)
- {
- if (hist[i] > 0 && i < minh)minh = i;
- if (hist[i] > 0 && i > maxh)maxh = i;
- }
- T = minh + maxh;
- T /= 2;
- double convergence = 0;
- cout << "Prag conergenta: ";
- cin >> convergence;
- int umin, umax;
- int smin, smax;
- while(true)
- {
- umin = umax = 0;
- smin = smax = 0;
- for(int i = 0; i < 255; i++)
- {
- if (i < T) umin += i * hist[i], smin += hist[i];
- if (i > T) umax += i * hist[i], smax += hist[i];
- }
- umin /= smin;
- umax /= smax;
- if (abs((umin + umax) / 2 - T) < convergence) break;
- T = (umin + umax) / 2;
- }
- cout << "Pragul gasit: " << T << endl;
- Mat binarized = Mat::zeros(cv::Size(width, height), CV_8UC1);
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- binarized.at<uchar>(y, x) = src.at<uchar>(y, x) > T ? 255 : 0;
- imshow("Binarized", binarized);
- waitKey();
- destroyAllWindows();
- }
- }
- void photoshop101()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- imshow("Original", src);
- int height = src.rows;
- int width = src.cols;
- int *hist = calcHistogram(src);
- int *procHist;
- int T = 127;
- int minh = 255;
- int maxh = 0;
- for (int i = 0; i < 255; i++)
- {
- if (hist[i] > 0 && i < minh)minh = i;
- if (hist[i] > 0 && i > maxh)maxh = i;
- }
- Mat negativ = src.clone();
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- negativ.at<uchar>(y, x) = 255 - src.at<uchar>(y, x);
- imshow("Negativ", negativ);
- procHist = calcHistogram(negativ);
- showHistogram("Negativ Hist", procHist, 255, 200);
- showHistogram("Original Hist", hist, 255, 200);
- waitKey(10);
- int omin, omax;
- cout << "Minim iesire: "; cin >> omin;
- cout << "Maxim iesire: "; cin >> omax;
- double factor = 1.0*(omax - omin) / (maxh - minh);
- Mat linScale = src.clone();
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- linScale.at<uchar>(y, x) = (int)max(min(omin + (src.at<uchar>(y, x) - minh)*factor, 255),0);
- imshow("Linear Scale", linScale);
- procHist = calcHistogram(linScale);
- showHistogram("Linear Hist", procHist, 255, 200);
- waitKey(10);
- double gamma = 0.0;
- cout << "Gamma correction: "; cin >> gamma;
- Mat gammaCorrected = src.clone();
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- gammaCorrected.at<uchar>(y, x) = (int)(pow(src.at<uchar>(y, x)/255.0, gamma) * 255);
- imshow("Gamma Corrected", gammaCorrected);
- procHist = calcHistogram(gammaCorrected);
- showHistogram("Gamma Hist", procHist, 255, 200);
- waitKey(10);
- int brightness = 0;
- cout << "Brightness: "; cin >> brightness;
- Mat brightened = src.clone();
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- brightened.at<uchar>(y, x) = (int)max(min(src.at<uchar>(y, x) + brightness, 255), 0);
- imshow("Brightness Corrected", brightened);
- procHist = calcHistogram(brightened);
- showHistogram("Brightness Hist", procHist, 255, 200);
- waitKey();
- destroyAllWindows();
- }
- }
- void equalizeHist()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- imshow("Original", src);
- int height = src.rows;
- int width = src.cols;
- int *hist = calcHistogram(src);
- int *procHist;
- int T = 127;
- int minh = 255;
- int maxh = 0;
- for (int i = 0; i < 255; i++)
- {
- if (hist[i] > 0 && i < minh) minh = i;
- if (hist[i] > 0 && i > maxh) maxh = i;
- }
- showHistogram("Original Hist", hist, 255, 200);
- waitKey(10);
- int *chist = calcHistogram(src);
- double *nchist = calcNHistogram(chist, width, height);
- int *reverse = calcHistogram(src);
- for (int i = 1; i < 255; i++)
- {
- nchist[i] += nchist[i - 1];
- }
- for (int i = 1; i < 254; i++)
- {
- if ((int)(nchist[i + 1] * 255) > i || (int)(nchist[i - 1] * 255) < i)
- reverse[i] = (int)(nchist[i] * 255);
- else
- reverse[i] = i;
- }
- showHistogram("CDF", nchist, 255, 200);
- Mat equalized = src.clone();
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- equalized.at<uchar>(y, x) = reverse[src.at<uchar>(y, x)];
- imshow("Equalized", equalized);
- procHist = calcHistogram(equalized);
- showHistogram("Equalized Hist", procHist, 255, 200);
- nchist = calcNHistogram(procHist, width, height);
- for (int i = 1; i < 255; i++)
- nchist[i] += nchist[i - 1];
- showHistogram("Equalized CDF", nchist, 255, 200);
- waitKey(10);
- waitKey();
- destroyAllWindows();
- }
- }
- void convolve(Mat res, Mat src, Mat filter, bool normalize = true, bool asDeltaMagnitude = false)
- {
- int height = src.rows;
- int width = src.cols;
- int f_height = (filter.rows - 1) / 2;
- int f_width = (filter.cols - 1) / 2;
- double sum = 0.0;
- double sumn = 0.0;
- for (int y = 0; y < filter.rows; y++)
- for (int x = 0; x < filter.cols; x++)
- if(filter.at<short>(y, x) > 0)
- sum += filter.at<short>(y, x);
- else
- sumn -= filter.at<short>(y, x);
- sum = sum + sumn;
- for(int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- double current_pixel = 0.0;
- for(int dy =-f_height; dy <=f_height; dy++)
- for (int dx = -f_width; dx <= f_width; dx++)
- {
- int cx = x + dx;
- cx = cx < 0 ? 0 : cx;
- cx = cx >= width ? width-1 : cx;
- int cy = y + dy;
- cy = cy < 0 ? 0 : cy;
- cy = cy >= height ? height - 1 : cy;
- current_pixel += (int)filter.at<short>(f_height + dy, f_width + dx) * src.at<uchar>(cy,cx);
- }
- if (abs(sum) > 0.01 & normalize)
- {
- current_pixel += sumn * 255;
- current_pixel /= sum;
- }
- if (asDeltaMagnitude)
- current_pixel = abs(current_pixel - 127) * 2;
- current_pixel = current_pixel > 255 ? 255 : current_pixel;
- current_pixel = current_pixel < 0 ? 0 : current_pixel;
- res.at<uchar>(y, x) = (uchar)current_pixel;
- }
- }
- Mat convolveImg(Mat img, Mat filter)
- {
- int height = img.rows;
- int width = img.cols;
- int fheight = filter.rows;
- int fwidth = filter.cols;
- int fsize = fwidth * fheight;
- int fh_start = -fheight / 2;
- int fh_end = fheight / 2;
- int fw_start = -fwidth / 2;
- int fw_end = fwidth / 2;
- Mat res = Mat::zeros(height, width, CV_8UC1);
- for(int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- int sum = 0;
- int count = fsize;
- for (int fy = fh_start; fy < fh_end; fy++)
- for (int fx = fw_start; fx < fw_end; fx++)
- {
- int nx = x + fx;
- int ny = y + fy;
- if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
- int local_dif = img.at<uchar>(ny, nx) - filter.at<uchar>(fy - fh_start, fx - fw_start);
- local_dif *= local_dif;
- sum += local_dif;
- count--;
- }
- sum /= fsize;
- sum = sqrt(sum);
- //sum *= sum;
- //sum /= 255;
- //sum = 255 - sum;
- //sum += 127 * count / fsize;
- res.at<uchar>(y, x) = (uchar)sum;
- }
- return res;
- }
- int convolveImgI(Mat img, Mat filter)
- {
- int height = img.rows;
- int width = img.cols;
- int fheight = filter.rows;
- int fwidth = filter.cols;
- int fsize = fwidth * fheight;
- int fh_start = -(fheight / 2);
- int fh_end = fheight / 2;
- int fw_start = -(fwidth / 2);
- int fw_end = fwidth / 2;
- int total = 255 * 255;
- int count_total = 0;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- int sum = 0;
- int count = fsize;
- for (int fy = fh_start; fy < fh_end; fy++)
- {
- for (int fx = fw_start; fx < fw_end; fx++)
- {
- int nx = x + fx;
- int ny = y + fy;
- if (nx < 0 || nx >= width || ny < 0 || ny >= height)continue;
- int local_dif = img.at<uchar>(ny, nx) - filter.at<uchar>(fy - fh_start, fx - fw_start);
- local_dif *= local_dif;
- sum += local_dif;
- //count--;
- }
- }
- sum /= fsize;
- sum = sqrt(sum);
- //sum *= sum;
- //sum /= 255;
- //sum = 255 - sum;
- //sum += 127 * count / fsize;
- count_total++;
- total = sum < total ? sum : total;
- }
- //total /= count_total;
- return total;
- }
- int total_conv(Mat img, Mat filter, int y)
- {
- int height = img.rows;
- int width = img.cols;
- int fheight = filter.rows;
- int fwidth = filter.cols;
- int fsize = fwidth * fheight;
- int fh_start = -(fheight / 2);
- int fh_end = fheight / 2;
- int fw_start = -(fwidth / 2);
- int fw_end = fwidth / 2;
- int total = 255 * 255;
- for (int x = 0; x < width; x++)
- {
- int sum = 0;
- //#pragma omp parallel for reduction(+:sum)
- for (int fy = fh_start; fy < fh_end; fy++)
- {
- for (int fx = fw_start; fx < fw_end; fx++)
- {
- int nx = x + fx;
- int ny = y + fy;
- if (nx < 0 || nx >= width || ny < 0 || ny >= height)continue;
- int local_dif = img.at<uchar>(ny, nx) - filter.at<uchar>(fy - fh_start, fx - fw_start);
- local_dif *= local_dif;
- sum += local_dif;
- }
- }
- sum /= fsize;
- sum = sqrt(sum);
- total = sum < total ? sum : total;
- }
- return total;
- }
- int convolveImgIP(Mat img, Mat filter)
- {
- int height = img.rows;
- int* totals = (int*)malloc(4 * height);
- int total = 255 * 255;
- //#pragma omp parallel for
- /*#pragma omp parallel sections
- {
- { if(height > 1) totals[0] = total_conv(img, filter, 0); }
- #pragma omp section
- { if (height > 2) totals[1] = total_conv(img, filter, 1); }
- #pragma omp section
- { if (height > 3) totals[2] = total_conv(img, filter, 2); }
- #pragma omp section
- { if (height > 4) totals[3] = total_conv(img, filter, 3); }
- #pragma omp section
- { if (height > 5) totals[4] = total_conv(img, filter, 4); }
- }*/
- for (int i = 0; i < height; i++)
- totals[i] = total_conv(img, filter, i);
- for (int i = 0; i < height; i++)
- total = totals[i] < total ? totals[i] : total;
- return total;
- }
- void lowHighPass()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- imshow("Original", src);
- int height = src.rows;
- int width = src.cols;
- Mat lowPassFilter = Mat(3, 3, CV_16SC1);
- for(int y = 0; y < lowPassFilter.rows; y++)
- for (int x = 0; x < lowPassFilter.cols; x++)
- lowPassFilter.at<short>(y, x) = 1;
- Mat gaussianFilter = Mat(3, 3, CV_16SC1);
- for (int y = 0; y < 3; y++)
- for (int x = 0; x < 3; x++)
- {
- if (x == 0 & y == 0 || x == 2 & y == 0 || x == 0 & y == 2 || x == 2 & y == 2)
- gaussianFilter.at<short>(y, x) = 1;
- if (x == 0 & y == 1 || x == 1 & y == 0 || x == 1 & y == 2 || x == 2 & y == 1)
- gaussianFilter.at<short>(y, x) = 2;
- if (x == 1 & y == 1)
- gaussianFilter.at<short>(y, x) = 4;
- }
- Mat highPassFilter = Mat(3, 3, CV_16SC1);
- for (int y = 0; y < highPassFilter.rows; y++)
- for (int x = 0; x < highPassFilter.cols; x++)
- highPassFilter.at<short>(y, x) = -1;
- highPassFilter.at<short>(highPassFilter.rows/2, highPassFilter.cols/2) =
- highPassFilter.rows * highPassFilter.cols;
- Mat laplaceFilter = Mat(3, 3, CV_16SC1);
- for (int y = 0; y < lowPassFilter.rows; y++)
- for (int x = 0; x < lowPassFilter.cols; x++)
- laplaceFilter.at<short>(y, x) = -1;
- laplaceFilter.at<short>(laplaceFilter.rows / 2, laplaceFilter.cols / 2) =
- laplaceFilter.rows * laplaceFilter.cols - 1;
- Mat lowPass = src.clone();
- convolve(lowPass, src, lowPassFilter);
- imshow("LowPass", lowPass);
- waitKey(10);
- Mat gaussPass = src.clone();
- convolve(gaussPass, src, gaussianFilter);
- imshow("GaussPass", gaussPass);
- waitKey(10);
- Mat highPass = src.clone();
- convolve(highPass, src, highPassFilter);
- imshow("highPass", highPass);
- waitKey(10);
- Mat laplacePass = src.clone();
- convolve(laplacePass, lowPass, laplaceFilter, false);
- imshow("laplacePass", laplacePass);
- waitKey(10);
- waitKey();
- destroyAllWindows();
- }
- }
- void centering_transform(Mat src)
- {
- int height = src.rows;
- int width = src.cols;
- for (int y = 0; y < src.rows; y++)
- for (int x = 0; x < src.cols; x++)
- if ((x + y) % 2 == 1)
- src.at<float>(y, x) = -src.at<float>(y, x);
- }
- Mat generic_frequency_domain_filter(Mat src) {
- //imaginea trebuie să aibă elemente de tip float
- Mat srcf;
- src.convertTo(srcf, CV_32FC1);
- //aplicarea transformatei Fourier, se obține o imagine cu valori numere complexe
- Mat fourier;
- centering_transform(srcf);
- dft(srcf, fourier, DFT_COMPLEX_OUTPUT);
- //divizare în două canale: partea reală și partea imaginară
- Mat channels[] = { Mat::zeros(src.size(), CV_32F), Mat::zeros(src.size(), CV_32F) };
- split(fourier, channels); // channels[0] = Re(DFT(I)), channels[1] = Im(DFT(I))
- //calcularea magnitudinii și fazei în imaginile mag, respectiv phi, cu elemente de tip float
- Mat mag, phi;
- magnitude(channels[0], channels[1], mag);
- phase(channels[0], channels[1], phi);
- //aici afișați imaginile cu fazele și magnitudinile
- Mat lmag = mag.clone();
- for (int y = 0; y < lmag.rows; y++)
- for (int x = 0; x < lmag.cols; x++)
- lmag.at<float>(y, x) = log(lmag.at<float>(y, x) + 1);
- Mat magu, phase;
- normalize(lmag, magu, 0, 255, NORM_MINMAX, CV_8UC1);
- normalize(phi, phase, 0, 255, NORM_MINMAX, CV_8UC1);
- imshow("Mag", magu);
- imshow("Pahse", phase);
- waitKey(10);
- //aici inserați operații de filtrare aplicate pe coeficienții Fourier
- /*for (int y = 0; y < lmag.rows; y++)
- for (int x = 0; x < lmag.cols; x++)
- {
- int dy = y - lmag.rows/2;
- int dx = x - lmag.cols/2;
- if (sqrt(dx*dx + dy * dy) > 20)
- mag.at<float>(y, x) = 0.0f;
- }*/
- for (int y = 0; y < lmag.rows; y++)
- for (int x = 0; x < lmag.cols; x++)
- {
- int dy = y - lmag.rows / 2;
- int dx = x - lmag.cols / 2;
- if (sqrt(dx*dx + dy * dy) > 20)
- mag.at<float>(y, x) = 0.0f;
- }
- //memorați partea reală în channels[0] și partea imaginară în channels[1]
- for (int y = 0; y < lmag.rows; y++)
- for (int x = 0; x < lmag.cols; x++)
- {
- channels[0].at<float>(y, x) = mag.at<float>(y, x) * cos(phi.at<float>(y, x));
- channels[1].at<float>(y, x) = mag.at<float>(y, x) * sin(phi.at<float>(y, x));
- }
- //aplicarea transformatei Fourier inversă și punerea rezultatului în dstf
- Mat dst, dstf;
- merge(channels, 2, fourier);
- dft(fourier, dstf, DFT_INVERSE | DFT_REAL_OUTPUT | DFT_SCALE);
- //transformarea de centrare inversă
- centering_transform(dstf);
- //normalizarea rezultatului în imaginea destinație
- normalize(dstf, dst, 0, 255, NORM_MINMAX, CV_8UC1);
- return dst;
- }
- void frequencyFilters()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- imshow("Original", src);
- int height = src.rows;
- int width = src.cols;
- Mat res = generic_frequency_domain_filter(src);
- imshow("Fourier Reconstr", res);
- waitKey(10);
- waitKey();
- destroyAllWindows();
- }
- }
- Mat variance(Mat image, int window_size)
- {
- int width = image.cols;
- int height = image.rows;
- Mat res = Mat::zeros(height, width, CV_8UC1);
- for(int y = 0; y < height - window_size; y++)
- for (int x = 0; x < width - window_size; x++)
- {
- int mean = 0;
- for (int wy = 0; wy < window_size; wy++)
- for (int wx = 0; wx < window_size; wx++)
- {
- int nx = x + wx;
- int ny = y + wy;
- mean += image.at<uchar>(ny, nx);
- }
- mean /= window_size * window_size;
- int var = 0;
- for (int wy = 0; wy < window_size; wy++)
- for (int wx = 0; wx < window_size; wx++)
- {
- int nx = x + wx;
- int ny = y + wy;
- var += abs(image.at<uchar>(ny, nx) - mean);
- }
- var /= window_size * window_size;
- res.at<uchar>(y + window_size / 2, x + window_size / 2) = var;
- }
- return res;
- }
- uchar meanI(Mat image)
- {
- int width = image.cols;
- int height = image.rows;
- int mean = 0;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- mean += image.at<uchar>(y, x);
- }
- mean /= width * height;
- return mean;
- }
- Mat varianceDistance(Mat image, Mat filter, int filterMean)
- {
- int width = image.cols;
- int height = image.rows;
- int fheight = filter.rows;
- int fwidth = filter.cols;
- Mat res = Mat::zeros(height, width, CV_8UC1);
- for (int y = -fheight/2; y < height; y++)
- for (int x = -fwidth/2; x < width; x++)
- {
- if (y + fheight / 2 >= height || x + fwidth / 2 >= width) continue;
- int mean = 0;
- for (int wy = 0; wy < fheight; wy++)
- for (int wx = 0; wx < fwidth; wx++)
- {
- int nx = x + wx;
- int ny = y + wy;
- if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
- mean += image.at<uchar>(ny, nx);
- }
- mean /= fwidth * fheight;
- int var = 0;
- for (int wy = 0; wy < fheight; wy++)
- for (int wx = 0; wx < fwidth; wx++)
- {
- int nx = x + wx;
- int ny = y + wy;
- if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
- int delta = (image.at<uchar>(ny, nx) - mean) - (filter.at<uchar>(wy, wx) - filterMean);
- var += delta * delta;
- }
- var /= fwidth * fheight;
- var = sqrt(var);
- res.at<uchar>(y + fheight / 2, x + fwidth / 2) = var;
- }
- return res;
- }
- Mat filterPeaks(Mat image)
- {
- Mat res = image.clone();
- int width = image.cols;
- int height = image.rows;
- for(int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- auto ns = getNeighbours(x, y, width, height);
- for (auto n : ns)
- {
- if (image.at<uchar>(n.y, n.x) <= image.at<uchar>(y, x))
- res.at<uchar>(n.y, n.x) = 0;
- }
- }
- return res;
- }
- int TopPercThreshold(Mat img, int low, int high, double topPercent)
- {
- int height = img.rows;
- int width = img.cols;
- int hist[256] = { 0 };
- int count = 0;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- {
- if (img.at<uchar>(y, x) >= low && img.at<uchar>(y, x) <= high)
- hist[img.at<uchar>(y, x)]++, count++;
- }
- int top = (1.0-topPercent) * count;
- int thresh = 256;
- while(count > top)
- count -= hist[--thresh];
- return thresh;
- }
- Mat cutBelow(Mat img, int thresh)
- {
- Mat res = img.clone();
- int height = img.rows;
- int width = img.cols;
- for (int y = 0; y < height; y++)
- for (int x = 0; x < width; x++)
- if (img.at<uchar>(y, x) < thresh)
- res.at<uchar>(y, x) = 0;
- return res;
- }
- /*regular grid*/
- vector<Mat> extractFeatures(Mat image)
- {
- int width = image.cols;
- int height = image.rows;
- /*96x96 / 12 = 8x8 features; 8 = ~8% * 96*/
- int divisionFactor = 8;
- int featureWidth = width / divisionFactor;
- int featureHeight = height / divisionFactor;
- vector<Mat> features;
- Mat var = variance(image, 10);
- Mat filtered_var = filterPeaks(var);
- Mat var3 = variance(image, 3);
- Mat filtered_var3 = filterPeaks(var3);
- int topThresh = TopPercThreshold(filtered_var3, 1, 255, 0.2);
- filtered_var3 = cutBelow(filtered_var3, topThresh);
- Mat threshvar3 = cutBelow(var3, topThresh);
- for(int y = 0; y < height; y++)
- for(int x = 0; x < width; x++)
- {
- if(filtered_var3.at<uchar>(y,x) > 0)
- {
- int xmin = x - 1 , xmax = x + 1;
- int ymin = y - 1, ymax = y + 1;
- queue<Point2i> Q;
- Q.push(Point2i(x, y));
- while (!Q.empty() && ymax - ymin <= 13 && xmax - xmin <= 13)
- {
- Point2i curr = Q.front();
- Q.pop();
- threshvar3.at<uchar>(curr.y, curr.x) = 0;
- auto ns = getNeighbours(curr.x, curr.y, width, height);
- for (auto n : ns)
- {
- if (threshvar3.at<uchar>(n.y, n.x) > 0)
- {
- Q.push(n);
- if (n.x > xmax) xmax = n.x;
- if (n.x < xmin) xmin = n.x;
- if (n.y > ymax) ymax = n.y;
- if (n.y < ymin) ymin = n.y;
- }
- }
- }
- if (ymax - ymin > 13)
- ymin = y - 6, ymax = y + 6;
- if (xmax - xmin > 13)
- xmin = x - 6, xmax = x + 6;
- if (xmin < 0) xmin = 0;
- if (xmax >= width) xmax = width - 1;
- if (ymin < 0) ymin = 0;
- if (ymax >= height) ymax = height - 1;
- //Clear region with black
- for (int ty = ymin; ty <= ymax; ty++)
- for (int tx = xmin; tx <= xmax; tx++)
- threshvar3.at<uchar>(ty, tx) = 0, filtered_var3.at<uchar>(ty, tx) = 0;
- //Mat last = image(Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1));
- auto r = Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
- features.push_back(image(r));
- }
- }
- return features;
- }
- vector<string> GetDirectoryFiles(const string& path) {
- vector<string> files;
- for (const auto& entry : filesystem::directory_iterator(path))
- {
- cout << entry.path() << endl;
- files.push_back(entry.path().string());
- }
- return files;
- }
- void preProcessImages()
- {
- vector<string> files = GetDirectoryFiles(".\\Images\\data\\2");
- cout << "Prerocessing files.." << endl;
- vector<Mat> all_features;
- for each (string s in files)
- {
- Mat image = imread(s.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
- vector<Mat> features = extractFeatures(image);
- all_features.insert(all_features.end(), features.begin(), features.end());
- for (auto feature : features)
- {
- uchar mean = meanI(feature);
- Mat res = varianceDistance(image, feature, mean);
- Mat conv_res = convolveImg(image, feature);
- cout << res;
- cout << conv_res;
- }
- }
- cout << "Features gathered: " << all_features.size() << endl;
- vector<Mat> trimmed_features;
- int count_convolutions = 0;
- for(int i = 0; i < all_features.size(); i++)
- {
- bool ok = true;
- for (int j = 0; j < all_features.size(); j++)
- {
- if (i == j)
- continue;
- count_convolutions++;
- if (count_convolutions % 1000000 == 0)
- cout << count_convolutions << endl;;
- int conv_total = convolveImgIP(all_features[i], all_features[j]);
- if (conv_total < 10)
- {
- /*
- Mat conv_res = convolveImg(all_features[i], all_features[j]);
- cout << conv_total << " ";
- cout << conv_res.size() << endl;
- */
- ok = false;
- }
- }
- if (ok) trimmed_features.push_back(all_features[i]);
- }
- cout << "Kept " << trimmed_features.size() << "features" <<endl;
- for each (string s in files)
- {
- Mat image = imread(s.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
- for each (Mat feature in trimmed_features) {
- Mat conv = convolveImg(image, feature);
- cout << "conv";
- }
- }
- cout << "All images have been translated to features"<< endl;
- system("pause>nul");
- }
- Mat InformationDesity(Mat img)
- {
- Mat laplaceFilter = Mat(3, 3, CV_16SC1);
- for (int y = 0; y < laplaceFilter.rows; y++)
- for (int x = 0; x < laplaceFilter.cols; x++)
- laplaceFilter.at<short>(y, x) = -1;
- laplaceFilter.at<short>(laplaceFilter.rows / 2, laplaceFilter.cols / 2) =
- laplaceFilter.rows * laplaceFilter.cols - 1;
- Mat lowPass = img.clone();
- convolve(lowPass, img, laplaceFilter,false,true);
- return lowPass;
- }
- void testInfoDensity()
- {
- char fname[MAX_PATH];
- while (openFileDlg(fname))
- {
- Mat src;
- src = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
- imshow("Original", src);
- int height = src.rows;
- int width = src.cols;
- Mat res = InformationDesity(src);
- imshow("Info Desity", res);
- waitKey(10);
- waitKey();
- destroyAllWindows();
- }
- }
- int main()
- {
- preProcessImages();
- /*Point2i currentPoint;
- Point2i neighbourPoint;
- int dir;
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10, 7);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);
- nextNeigh(currentPoint, &neighbourPoint, &dir, 8, 10, 10);*/
- int op;
- do
- {
- system("cls");
- destroyAllWindows();
- printf("Menu:\n");
- printf(" 1 - Open image\n");
- printf(" 2 - Open BMP images from folder\n");
- printf(" 3 - Image negative - diblook style\n");
- printf(" 4 - BGR->HSV\n");
- printf(" 5 - Resize image\n");
- printf(" 6 - Canny edge detection\n");
- printf(" 7 - Edges in a video sequence\n");
- printf(" 8 - Snap frame from live video\n");
- printf(" 9 - Mouse callback demo\n");
- printf(" 10 - Add gray\n");
- printf(" 11 - Mult gray\n");
- printf(" 12 - Flag\n");
- printf(" 13 - Inversa Matrice 3x3\n");
- printf(" 14 - RGB to 3 gray\n");
- printf(" 15 - RGB to 1 gray\n");
- printf(" 16 - RGB ro H,S,V\n");
- printf(" 17 - testam negative_image()\n");
- printf(" 18 - testThreshold\n");
- printf(" 19 - IsInside\n");
- printf(" 20 - L3 Hist 1-4\n");
- printf(" 21 - L3 Hist Bins 5-6\n");
- printf(" 22 - L3 Hue Reduce 7\n");
- printf(" 23 - L3 Hist Bins 6\n");
- printf(" 24 - L4 Process Object\n");
- printf(" 25 - Label Objects BFS\n");
- printf(" 26 - Label Objects 2 steps\n");
- printf(" 27 - Find Border\n");
- printf(" 28 - Reconstruct Border\n");
- printf(" 29 - Erode Dilate\n");
- printf(" 30 - Fill Ero\n");
- printf(" 31 - Med, std dev, cfdp\n");
- printf(" 32 - Auto Binarize\n");
- printf(" 33 - Photoshop 101\n");
- printf(" 34 - Equalize Histogram\n");
- printf(" 35 - Convolutions\n");
- printf(" 36 - Fourier\n");
- printf(" 0 - Exit\n\n");
- printf("Option: ");
- scanf("%d",&op);
- switch (op)
- {
- case 1:
- testOpenImage();
- break;
- case 2:
- testOpenImagesFld();
- break;
- case 3:
- testParcurgereSimplaDiblookStyle(); //diblook style
- break;
- case 4:
- //testColor2Gray();
- testBGR2HSV();
- break;
- case 5:
- testResize();
- break;
- case 6:
- testCanny();
- break;
- case 7:
- testVideoSequence();
- break;
- case 8:
- testSnap();
- break;
- case 9:
- testMouseClick();
- break;
- case 10:
- testNegativeImageP();
- break;
- case 11:
- testNegativeImageM();
- break;
- case 12:
- test4Flag();
- break;
- case 13:
- testInvMat3f();
- break;
- case 14:
- testRGBComp();
- break;
- case 15:
- testRGBGray();
- break;
- case 16:
- testRGBHSV();
- break;
- case 17:
- negative_image();
- break;
- case 18:
- testThreshold();
- break;
- case 19:
- testIsInside();
- break;
- case 20:
- testL3Hist14();
- break;
- case 21:
- testL3Bins56();
- break;
- case 22:
- testL3Reduce7();
- break;
- case 23:
- floyd_steinberg_dithering();
- break;
- case 24:
- processObjects();
- break;
- case 25:
- labelObjects();
- break;
- case 26:
- labelObjects2Steps();
- break;
- case 27:
- findBorder();
- break;
- case 28:
- reconstruct();
- break;
- case 29:
- EroDil();
- break;
- case 30:
- FillEro();
- break;
- case 31:
- imgStats();
- break;
- case 32:
- autoBinarizeBimodal();
- break;
- case 33:
- photoshop101();
- break;
- case 34:
- equalizeHist();
- break;
- case 35:
- lowHighPass();
- break;
- case 36:
- frequencyFilters();
- break;
- case 37:
- testInfoDensity();
- break;
- }
- }while (op!=0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement