diff --git a/.gitignore b/.gitignore index c4c4ffc..af19828 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,17 @@ *.zip +*.pyc +*.dat +*.png +*_material +__*__ +descriptors* +classification_descriptors +hidden +compressed +trash +Data +SpatioTemporal +report +kodikas_diagrammata.txt +alternative_harris.py +makegif.py diff --git a/README.md b/README.md index 2ab2fd1..179576d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ # ntua-cv-lab This is a private repository for the version control of the lab projects of the Computer Vision course of ECE NTUA + +In order for the code to be properly run, the scripts have to executed in an environment with opencv, numpy, scikit-learn, tqdm, and matplotlib. For jupyter support, jupyter and nb_conda_kernels should also be included. Following is a command to create a virtual environment in conda. + +``` +conda create -n cv_lab1_env python=3.7 opencv=3.4.2 numpy scikit-learn tqdm matplotlib jupyter nb_conda_kernels + +conda activate cv_lab1_env +``` + +Numba (a just in time compiler for python) should also be installed in order for the box_detection scripts to be fast. + +``` +conda install numba +``` diff --git a/lab1/cv23_lab1_part12_material.zip b/lab1/cv23_lab1_part12_material.zip deleted file mode 100644 index f5c59d8..0000000 Binary files a/lab1/cv23_lab1_part12_material.zip and /dev/null differ diff --git a/lab1/cvlab1.py b/lab1/cvlab1.py deleted file mode 100644 index 8f3ba34..0000000 --- a/lab1/cvlab1.py +++ /dev/null @@ -1,101 +0,0 @@ -import cv2 -import matplotlib.pyplot as plt -import numpy as np - -# enable interactive mode -# plt.ion() - -# ================= BEG FUNCTIONS ================= # -def getpsnr(image, noisestd): - return 20*log10((np.max(image)-np.min(image))/noisestd) - -def getstd(image, psnr): - return (np.max(image)-np.min(image))/(10**(psnr/20)) - -def gaussian2d(x, y, x0, y0, sigmax, sigmay, a): - return a*np.exp(-((x-x0)**2/(2*sigmax**2)+(y-y0)**2/(2*sigmay**2))) - -def my2dconv(image, kernel): - ix, iy = image.shape - nx, ny = kernel.shape - result = np.zeros((ix + nx - 1, iy + ny - 1)) - padded = np.pad(image, [(nx//2, nx//2),(ny//2,ny//2)], mode='constant') - for i in range(nx//2, ix + nx//2): - for j in range(ny//2, iy + ny//2): - result[i,j] = np.sum(padded[i-nx//2:i+nx//2+1,j-ny//2:j+ny//2+1] * kernel) - return result[nx//2:ix+nx//2, ny//2:iy+ny//2] - -def myfilter(sigma, method): - if (method == "gaussian"): - n = int(np.ceil(3*sigma)*2 + 1) - # generating the kernels using meshgrid is - # said to be more accurate than multiplying - # two 1d gaussian kernels together. That is - # because the product of two gaussian functions - # is not neccessarily a gaussian function, so - # there may be a loss of symmetry between the - # x, y axis. - x, y = np.meshgrid(np.arange(-n//2+1, n//2+1), - np.arange(-n//2+1, n//2+1)) - kernel = np.exp(-(x**2+y**2)/(2*sigma**2)) - # this isn't really necessary, it preserves brightness - kernel = kernel/np.sum(kernel) - return kernel - if (method == "log"): - n = int(np.ceil(3*sigma)*2 + 1) - x, y = np.meshgrid(np.arange(-n//2+1, n//2+1), - np.arange(-n//2+1, n//2+1)) - kernel = np.exp(-(x**2+y**2)/(2*sigma**2)) - # this isn't really necessary, it preserves brightness - kernel = kernel/np.sum(kernel) - laplacian = np.array([[0,1,0], - [1,-4,1], - [0,1,0]]) - # perform the convolution between the gaussian kernel - # and the laplacian, in order to create the log kernel - logkernel = my2dconv(kernel, laplacian) - return logkernel - print("Error: method has to be either \"gaussian\" or \"log\"") - -# ================= END FUNCTIONS ================= # - -# read the image and convert to gray scale -image = cv2.imread("cv23_lab1_part12_material/edgetest_23.png", cv2.IMREAD_GRAYSCALE) - -# add noise to the images. 10db and 20db -image10db = image + np.random.normal(0, getstd(image, 10), image.shape) -image20db = image + np.random.normal(0, getstd(image, 20), image.shape) - -noised_images = [image10db, image20db] -for nsd_img in noised_images: - # plot the images - fig, axs = plt.subplots(1, 2) - axs[0].imshow(image, cmap='gray') - axs[1].imshow(nsd_img, cmap='gray') - axs[0].set_title("Original Image") - axs[1].set_title("Image with gaussian noise") - plt.show() - - # It can be seen that, indeed, the 10db PSNR gaussian noise - # is more intense than the 20db PSNR one. - sigma = 1.5 # 1.5 for 10db, 3 for 20db - gaussianfilter = myfilter(sigma, "gaussian") - img_gaussed = cv2.filter2D(nsd_img, -1, gaussianfilter) - - # laplacian on gaussian - logfilter1 = myfilter(sigma, "log") - img_loged1 = cv2.filter2D(nsd_img, -1, logfilter1) - - # non linear approximation of laplacian on gaussian - # using morphological operators - cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) - img_loged2 = cv2.dilate(img_gaussed, cross) + cv2.erode(img_gaussed, cross) - 2*img_gaussed - - fig, axs = plt.subplots(1, 3) - axs[0].imshow(img_gaussed, cmap='gray') - axs[0].set_title("Gaussianly Smoothed Image") - axs[1].imshow(img_loged1, cmap='gray') - axs[1].set_title("LoGed Image (Linear Approximation)") - axs[2].imshow(img_loged2, cmap='gray') - axs[2].set_title("LoGed Image (Non Linear Approximation)") - plt.show() diff --git a/lab1/image-plots/blob-detection-cells-bad.jpg b/lab1/image-plots/blob-detection-cells-bad.jpg new file mode 100644 index 0000000..3a1ccd2 Binary files /dev/null and b/lab1/image-plots/blob-detection-cells-bad.jpg differ diff --git a/lab1/image-plots/blob-detection-cells-good.jpg b/lab1/image-plots/blob-detection-cells-good.jpg new file mode 100644 index 0000000..f541ad6 Binary files /dev/null and b/lab1/image-plots/blob-detection-cells-good.jpg differ diff --git a/lab1/image-plots/blob-detection-cells.jpg b/lab1/image-plots/blob-detection-cells.jpg new file mode 100644 index 0000000..cac4130 Binary files /dev/null and b/lab1/image-plots/blob-detection-cells.jpg differ diff --git a/lab1/image-plots/blob-detection-ii-cells.jpg b/lab1/image-plots/blob-detection-ii-cells.jpg new file mode 100644 index 0000000..622d6c1 Binary files /dev/null and b/lab1/image-plots/blob-detection-ii-cells.jpg differ diff --git a/lab1/image-plots/blob-detection-ii-up.jpg b/lab1/image-plots/blob-detection-ii-up.jpg new file mode 100644 index 0000000..fa1dd95 Binary files /dev/null and b/lab1/image-plots/blob-detection-ii-up.jpg differ diff --git a/lab1/image-plots/blob-detection-multiscale-cells-bad.jpg b/lab1/image-plots/blob-detection-multiscale-cells-bad.jpg new file mode 100644 index 0000000..3c5a1fe Binary files /dev/null and b/lab1/image-plots/blob-detection-multiscale-cells-bad.jpg differ diff --git a/lab1/image-plots/blob-detection-multiscale-cells-good.jpg b/lab1/image-plots/blob-detection-multiscale-cells-good.jpg new file mode 100644 index 0000000..bd8f704 Binary files /dev/null and b/lab1/image-plots/blob-detection-multiscale-cells-good.jpg differ diff --git a/lab1/image-plots/blob-detection-multiscale-cells.jpg b/lab1/image-plots/blob-detection-multiscale-cells.jpg new file mode 100644 index 0000000..8faa5ad Binary files /dev/null and b/lab1/image-plots/blob-detection-multiscale-cells.jpg differ diff --git a/lab1/image-plots/blob-detection-multiscale-ii-cells.jpg b/lab1/image-plots/blob-detection-multiscale-ii-cells.jpg new file mode 100644 index 0000000..efa9dbd Binary files /dev/null and b/lab1/image-plots/blob-detection-multiscale-ii-cells.jpg differ diff --git a/lab1/image-plots/blob-detection-multiscale-ii-up.jpg b/lab1/image-plots/blob-detection-multiscale-ii-up.jpg new file mode 100644 index 0000000..dddd797 Binary files /dev/null and b/lab1/image-plots/blob-detection-multiscale-ii-up.jpg differ diff --git a/lab1/image-plots/blob-detection-multiscale-up.jpg b/lab1/image-plots/blob-detection-multiscale-up.jpg new file mode 100644 index 0000000..5415d1a Binary files /dev/null and b/lab1/image-plots/blob-detection-multiscale-up.jpg differ diff --git a/lab1/image-plots/blob-detection-up.jpg b/lab1/image-plots/blob-detection-up.jpg new file mode 100644 index 0000000..5bfcf33 Binary files /dev/null and b/lab1/image-plots/blob-detection-up.jpg differ diff --git a/lab1/image-plots/cells-gray.jpg b/lab1/image-plots/cells-gray.jpg new file mode 100644 index 0000000..c8a85e8 Binary files /dev/null and b/lab1/image-plots/cells-gray.jpg differ diff --git a/lab1/cv23_lab1_part12_material/cells.jpg b/lab1/image-plots/cells.jpg similarity index 100% rename from lab1/cv23_lab1_part12_material/cells.jpg rename to lab1/image-plots/cells.jpg diff --git a/lab1/image-plots/corner-detection-eigenvalues.jpg b/lab1/image-plots/corner-detection-eigenvalues.jpg new file mode 100644 index 0000000..7e28a26 Binary files /dev/null and b/lab1/image-plots/corner-detection-eigenvalues.jpg differ diff --git a/lab1/image-plots/corner-detection-multiscale.jpg b/lab1/image-plots/corner-detection-multiscale.jpg new file mode 100644 index 0000000..a3ada30 Binary files /dev/null and b/lab1/image-plots/corner-detection-multiscale.jpg differ diff --git a/lab1/image-plots/corner-detection.jpg b/lab1/image-plots/corner-detection.jpg new file mode 100644 index 0000000..f4e26d3 Binary files /dev/null and b/lab1/image-plots/corner-detection.jpg differ diff --git a/lab1/image-plots/edges-intro0.jpg b/lab1/image-plots/edges-intro0.jpg new file mode 100644 index 0000000..6c120f5 Binary files /dev/null and b/lab1/image-plots/edges-intro0.jpg differ diff --git a/lab1/image-plots/edges-intro1.jpg b/lab1/image-plots/edges-intro1.jpg new file mode 100644 index 0000000..85d17b5 Binary files /dev/null and b/lab1/image-plots/edges-intro1.jpg differ diff --git a/lab1/image-plots/edges-real.jpg b/lab1/image-plots/edges-real.jpg new file mode 100644 index 0000000..a120276 Binary files /dev/null and b/lab1/image-plots/edges-real.jpg differ diff --git a/lab1/cv23_lab1_part12_material/edgetest_23.png b/lab1/image-plots/edgetest_23.png similarity index 100% rename from lab1/cv23_lab1_part12_material/edgetest_23.png rename to lab1/image-plots/edgetest_23.png diff --git a/lab1/image-plots/grad-comparison.png b/lab1/image-plots/grad-comparison.png new file mode 100644 index 0000000..0151224 Binary files /dev/null and b/lab1/image-plots/grad-comparison.png differ diff --git a/lab1/image-plots/images-scaled/blob-detection-cells-bad-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-cells-bad-scaled.jpg new file mode 100644 index 0000000..530ef5b Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-cells-bad-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-cells-good-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-cells-good-scaled.jpg new file mode 100644 index 0000000..ce68a01 Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-cells-good-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-cells-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-cells-scaled.jpg new file mode 100644 index 0000000..43f9a45 Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-cells-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-bad-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-bad-scaled.jpg new file mode 100644 index 0000000..91eecfa Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-bad-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-good-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-good-scaled.jpg new file mode 100644 index 0000000..37f4a23 Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-good-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-scaled.jpg new file mode 100644 index 0000000..99b5478 Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-multiscale-cells-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jpg new file mode 100644 index 0000000..b85f932 Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg new file mode 100644 index 0000000..ce36f6b Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-multiscale-up-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-multiscale-up-scaled.jpg new file mode 100644 index 0000000..83a2e9d Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-multiscale-up-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/blob-detection-up-scaled.jpg b/lab1/image-plots/images-scaled/blob-detection-up-scaled.jpg new file mode 100644 index 0000000..cca8d05 Binary files /dev/null and b/lab1/image-plots/images-scaled/blob-detection-up-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/cells-gray-scaled.jpg b/lab1/image-plots/images-scaled/cells-gray-scaled.jpg new file mode 100644 index 0000000..238a1cc Binary files /dev/null and b/lab1/image-plots/images-scaled/cells-gray-scaled.jpg differ diff --git a/lab1/image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg b/lab1/image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg new file mode 100644 index 0000000..8a7c0a5 Binary files /dev/null and b/lab1/image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg differ diff --git a/lab1/cv23_lab1_part12_material/kyoto_edges.jpg b/lab1/image-plots/kyoto_edges.jpg similarity index 100% rename from lab1/cv23_lab1_part12_material/kyoto_edges.jpg rename to lab1/image-plots/kyoto_edges.jpg diff --git a/lab1/cv23_lab1_part12_material/up.png b/lab1/image-plots/up.png similarity index 100% rename from lab1/cv23_lab1_part12_material/up.png rename to lab1/image-plots/up.png diff --git a/lab1/part12/blob_detection.py b/lab1/part12/blob_detection.py new file mode 100644 index 0000000..16adb55 --- /dev/null +++ b/lab1/part12/blob_detection.py @@ -0,0 +1,67 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from cv23_lab1_part2_utils import interest_points_visualization + +# TESTED AND WORKING + +def blobtest(): + up = cv2.imread("cv23_lab1_part12_material/up.png") + up = cv2.cvtColor(up, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/up.png", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 2.5 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BlobDetection(gray, sigma, theta) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-up.jpg") + + # play around with the parameters + blobs = HessianLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-up.jpg") + + cells = cv2.imread("cv23_lab1_part12_material/cells.jpg") + cells = cv2.cvtColor(cells, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/cells.jpg", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 3 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BlobDetection(gray, sigma, theta) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-cells-bad.jpg") + + # play around with the parameters + blobs = HessianLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-cells-bad.jpg") + + # play around with the parameters + sigma = 3 + theta = 0.15 + scale = 1.1 + N = 8 + + blobs = BlobDetection(gray, sigma, theta) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-cells-good.jpg") + + # play around with the parameters + blobs = HessianLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-cells-good.jpg") + +blobtest() +plt.show() diff --git a/lab1/part12/blob_detection_utils.py b/lab1/part12/blob_detection_utils.py new file mode 100644 index 0000000..9c82a24 --- /dev/null +++ b/lab1/part12/blob_detection_utils.py @@ -0,0 +1,35 @@ +import numpy as np +import time +from intro_utils import smooth_gradient +from intro_utils import InterestPointCoord +from intro_utils import LogMetric + +def BlobDetection(image, sigma, theta): + gradxx, gradxy, gradyy = smooth_gradient(image, sigma, 2) + r = gradxx * gradyy - gradxy * gradxy # determinant of hessian + indices = InterestPointCoord(r, sigma, theta) + scale = sigma*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + return blobs + +def HessianLaplacian(image, sigma, theta, scale, N): + scales = [scale**i for i in list(range(N))] + sigmas = [scale * sigma for scale in scales] + + gradsxx = [] + gradsyy = [] + blobs_per_scale = [] + for s in sigmas: + lxx, lxy, lyy = smooth_gradient(image, s, 2) + r = lxx * lyy - lxy * lxy # determinant of hessian + indices = InterestPointCoord(r, s, theta) + scale = s*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + + gradsxx.append(lxx) + gradsyy.append(lyy) + blobs_per_scale.append(blobs) + + grads = list(zip(scales, gradsxx, gradsyy)) + logs = [(s**2)*np.abs(xx + yy) for (s, xx, yy) in grads] + return LogMetric(logs, blobs_per_scale, N) diff --git a/lab1/part12/box_detection.py b/lab1/part12/box_detection.py new file mode 100644 index 0000000..0291353 --- /dev/null +++ b/lab1/part12/box_detection.py @@ -0,0 +1,68 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from box_detection_utils import BoxFilters +from box_detection_utils import BoxLaplacian +from cv23_lab1_part2_utils import interest_points_visualization + +# THIS WORKS NOW, HOWEVER IT IS NOT SPED UP. +# THE SPEED UP ACTUALLY DEPENDS ON HOW THE +# SIMPLE BLOB DETECTION FUNCTION WORKS. + +# IF IT IS IMPLEMENTED USING THE BUILT IN +# FILTER2D AND GAUSSIAN FUNCTIONS, THEN +# IT IS ALREADY REALLY FAST AND ITS TIME +# COMPLEXITY DOES NOT DEPEND ON THE SIGMA +# PARAMETER. IF A MANUAL CONVOLUTION HAS +# BEEN USED, THEN A HUGE SPEEDUP (OR ACTUALLY SLOW DOWN) +# WILL BE NOTICEABLE. + +def boxtest(): + up = cv2.imread("cv23_lab1_part12_material/up.png") + up = cv2.cvtColor(up, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/up.png", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 2.5 + theta = 0.05 + + blobs = BoxFilters(gray, sigma, theta) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-ii-up.jpg") + + # play around with the parameters + sigma = 2.5 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BoxLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-ii-up.jpg") + + cells = cv2.imread("cv23_lab1_part12_material/cells.jpg") + cells = cv2.cvtColor(cells, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/cells.jpg", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 3 + theta = 0.05 + + blobs = BoxFilters(gray, sigma, theta) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-ii-cells.jpg") + + # play around with the parameters + sigma = 3 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BoxLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-ii-cells.jpg") + +boxtest() +plt.show() diff --git a/lab1/part12/box_detection_utils.py b/lab1/part12/box_detection_utils.py new file mode 100644 index 0000000..7783b1f --- /dev/null +++ b/lab1/part12/box_detection_utils.py @@ -0,0 +1,98 @@ +import numpy as np +import time +from intro_utils import LogMetric +from intro_utils import InterestPointCoord + + +def IntegralImage(i): + # this definitely works + return np.cumsum(np.cumsum(i, axis=0), axis=1) + +def BoxDerivative(image, sigma): + def roi(ii, x, y, padw): + # rectangle of interest + # the input image is padded, otherwise the shifts + # would have peculiar results + + # therefore remeber to unpad in the end + + # take the whole integral image and move it around + # the area outside of the rectangle will cancel itself out + # leaving only the values inside the rectangle of interest + shiftx = int((x + 1)/2 - 1) + shifty = int((y + 1)/2 - 1) + + # this isolates the upper and lower line + upline = np.roll(ii, shifty + 1, axis=0) + loline = np.roll(ii, -shifty, axis=0) + + # this isolates the upper corners + uprigh = np.roll(upline, -shiftx, axis=1) + upleft = np.roll(upline, shiftx+1, axis=1) + + # this isolates the lower corners + downri = np.roll(loline, -shiftx, axis=1) + downle = np.roll(loline, shiftx+1, axis=1) + + result = upleft - uprigh + downri - downle + # unpad in the end + result = result[padw:-padw, padw:-padw] + return result + + n = int(2*np.ceil(3*sigma) + 1) + height = int(4*np.floor(n/6) + 1) + width = int(2*np.floor(n/6) + 1) + padding = 2 * width + + padded = np.pad(image, padding, 'reflect') + ii = IntegralImage(padded) + + # sum the middle rectangle x(-3) and then add the whole rectangle + # (0 -3 0) + (1 1 1) = (1 -2 1) + lxx = -3*(roi(ii, width, height, padding)) + roi(ii, 3*width, height, padding) + lyy = -3*(roi(ii, height, width, padding)) + roi(ii, height, 3*width, padding) + + # the xy derivative requires a little special handling + smallbox = roi(ii, width, width, padding) + padded = np.pad(smallbox, padding, 'reflect') + shiftv = int((width-1)/2 + 1) + + ul = np.roll(padded, [shiftv, shiftv], axis=(0, 1)) + ur = np.roll(padded, [-shiftv, shiftv], axis=(0, 1)) + dl = np.roll(padded, [shiftv, -shiftv], axis=(0, 1)) + dr = np.roll(padded, [-shiftv, -shiftv], axis=(0, 1)) + + lxy = ul + dr - ur - dl + lxy = lxy[padding:-padding, padding:-padding] + + return (lxx, lxy, lyy) + +def BoxFilters(image, sigma, theta): + lxx, lxy, lyy = BoxDerivative(image, sigma) + r = lxx*lyy - (0.9*lxy)**2 + indices = InterestPointCoord(r, sigma, theta) + scale = sigma*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + return blobs + +def BoxLaplacian(image, sigma, theta, scale, N): + scales = [scale**i for i in list(range(N))] + sigmas = [scale * sigma for scale in scales] + + gradsxx = [] + gradsyy = [] + blobs_per_scale = [] + for s in sigmas: + lxx, lxy, lyy = BoxDerivative(image, s) + r = lxx*lyy - (0.9*lxy)**2 + indices = InterestPointCoord(r, s, theta) + scale = s*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + + gradsxx.append(lxx) + gradsyy.append(lyy) + blobs_per_scale.append(blobs) + + grads = list(zip(scales, gradsxx, gradsyy)) + logs = [(s**2)*np.abs(xx + yy) for (s, xx, yy) in grads] + return LogMetric(logs, blobs_per_scale, N) diff --git a/lab1/part12/corner_detection.py b/lab1/part12/corner_detection.py new file mode 100644 index 0000000..2531c1d --- /dev/null +++ b/lab1/part12/corner_detection.py @@ -0,0 +1,27 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from cv23_lab1_part2_utils import interest_points_visualization + +# TESTED AND WORKING + +def cornertest(): + kyoto = cv2.imread("cv23_lab1_part12_material/kyoto_edges.jpg") + kyoto = cv2.cvtColor(kyoto, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/kyoto_edges.jpg", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + corners = CornerDetection(gray, 2, 2.5, 0.005, 0.1) + interest_points_visualization(kyoto, corners, None) + plt.savefig(f"image-plots/corner-detection.jpg") + + # play around with the parameters + corners = HarrisLaplacian(gray, 2, 2.5, 0.005, 0.1, 1.1, 6) + interest_points_visualization(kyoto, corners, None) + plt.savefig(f"image-plots/corner-detection-multiscale.jpg") + +cornertest() +plt.show() diff --git a/lab1/part12/corner_detection_utils.py b/lab1/part12/corner_detection_utils.py new file mode 100644 index 0000000..4d30a22 --- /dev/null +++ b/lab1/part12/corner_detection_utils.py @@ -0,0 +1,73 @@ +import cv2 +import numpy as np +from intro_utils import myfilter +from intro_utils import smooth_gradient +from intro_utils import InterestPointCoord +from intro_utils import LogMetric +import matplotlib.pyplot as plt + +def CornerDetection(image, sigma, rho, theta, k): + # Keep in mind that the image is smoothed + # by default in the criterion function. + # r = CornerCriterion(image, sigma, rho, k) + + # calculate the gradient on both directions + gradx, grady = smooth_gradient(image, sigma, 1) + # calculate whatevere these elements are + Gr = myfilter(rho, "gaussian") + j1 = cv2.filter2D(gradx * gradx, -1, Gr) + j2 = cv2.filter2D(gradx * grady, -1, Gr) + j3 = cv2.filter2D(grady * grady, -1, Gr) + + # efficient way to calculate the eigenvalues + temp = j1 + j3 + lplus = 1/2*(temp + np.sqrt( (j1 - j3)**2 + 4*j2**2)) + lminus = temp - lplus + + # calculate the cornerness criterion + r = lplus * lminus - k*((lplus + lminus)**2) + + indices = InterestPointCoord(r, sigma, theta) + scale = sigma*np.ones((indices.shape[0], 1)) + corners = np.concatenate((indices, scale), axis=1) + + return corners + +def HarrisLaplacian(image, sigma, rho, theta, k, scale, N): + # Multiscale Corner Detection + scales = [scale**i for i in list(range(N))] + sigmas = [scale * sigma for scale in scales] + rhos = [scale * rho for scale in scales] + params = list(zip(sigmas, rhos)) + + gradsxx = [] + gradsyy = [] + corners_per_scale = [] + for (s, r) in params: + # calculate the gradient on both directions + gradx, grady, gradxx, _, gradyy = smooth_gradient(image, s, 3) + + # calculate whatevere these elements are + Gr = myfilter(r, "gaussian") + j1 = cv2.filter2D(gradx * gradx, -1, Gr) + j2 = cv2.filter2D(gradx * grady, -1, Gr) + j3 = cv2.filter2D(grady * grady, -1, Gr) + + # efficient way to calculate the eigenvalues + temp = j1 + j3 + lplus = 1/2*(temp + np.sqrt( (j1 - j3)**2 + 4*j2**2)) + lminus = temp - lplus + # calculate the cornerness criterion + r = lplus * lminus - k*((lplus + lminus)**2) + + indices = InterestPointCoord(r, s, theta) + scale = s*np.ones((indices.shape[0], 1)) + corners = np.concatenate((indices, scale), axis=1) + + gradsxx.append(gradxx) + gradsyy.append(gradyy) + corners_per_scale.append(corners) + + grads = list(zip(scales, gradsxx, gradsyy)) + logs = [(s**2)*np.abs(xx + yy) for (s, xx, yy) in grads] + return LogMetric(logs, corners_per_scale, N) diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/blob_detection.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/blob_detection.py new file mode 100644 index 0000000..16adb55 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/blob_detection.py @@ -0,0 +1,67 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from cv23_lab1_part2_utils import interest_points_visualization + +# TESTED AND WORKING + +def blobtest(): + up = cv2.imread("cv23_lab1_part12_material/up.png") + up = cv2.cvtColor(up, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/up.png", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 2.5 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BlobDetection(gray, sigma, theta) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-up.jpg") + + # play around with the parameters + blobs = HessianLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-up.jpg") + + cells = cv2.imread("cv23_lab1_part12_material/cells.jpg") + cells = cv2.cvtColor(cells, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/cells.jpg", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 3 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BlobDetection(gray, sigma, theta) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-cells-bad.jpg") + + # play around with the parameters + blobs = HessianLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-cells-bad.jpg") + + # play around with the parameters + sigma = 3 + theta = 0.15 + scale = 1.1 + N = 8 + + blobs = BlobDetection(gray, sigma, theta) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-cells-good.jpg") + + # play around with the parameters + blobs = HessianLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-cells-good.jpg") + +blobtest() +plt.show() diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/blob_detection_utils.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/blob_detection_utils.py new file mode 100644 index 0000000..9c82a24 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/blob_detection_utils.py @@ -0,0 +1,35 @@ +import numpy as np +import time +from intro_utils import smooth_gradient +from intro_utils import InterestPointCoord +from intro_utils import LogMetric + +def BlobDetection(image, sigma, theta): + gradxx, gradxy, gradyy = smooth_gradient(image, sigma, 2) + r = gradxx * gradyy - gradxy * gradxy # determinant of hessian + indices = InterestPointCoord(r, sigma, theta) + scale = sigma*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + return blobs + +def HessianLaplacian(image, sigma, theta, scale, N): + scales = [scale**i for i in list(range(N))] + sigmas = [scale * sigma for scale in scales] + + gradsxx = [] + gradsyy = [] + blobs_per_scale = [] + for s in sigmas: + lxx, lxy, lyy = smooth_gradient(image, s, 2) + r = lxx * lyy - lxy * lxy # determinant of hessian + indices = InterestPointCoord(r, s, theta) + scale = s*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + + gradsxx.append(lxx) + gradsyy.append(lyy) + blobs_per_scale.append(blobs) + + grads = list(zip(scales, gradsxx, gradsyy)) + logs = [(s**2)*np.abs(xx + yy) for (s, xx, yy) in grads] + return LogMetric(logs, blobs_per_scale, N) diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/box_detection.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/box_detection.py new file mode 100644 index 0000000..0291353 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/box_detection.py @@ -0,0 +1,68 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from box_detection_utils import BoxFilters +from box_detection_utils import BoxLaplacian +from cv23_lab1_part2_utils import interest_points_visualization + +# THIS WORKS NOW, HOWEVER IT IS NOT SPED UP. +# THE SPEED UP ACTUALLY DEPENDS ON HOW THE +# SIMPLE BLOB DETECTION FUNCTION WORKS. + +# IF IT IS IMPLEMENTED USING THE BUILT IN +# FILTER2D AND GAUSSIAN FUNCTIONS, THEN +# IT IS ALREADY REALLY FAST AND ITS TIME +# COMPLEXITY DOES NOT DEPEND ON THE SIGMA +# PARAMETER. IF A MANUAL CONVOLUTION HAS +# BEEN USED, THEN A HUGE SPEEDUP (OR ACTUALLY SLOW DOWN) +# WILL BE NOTICEABLE. + +def boxtest(): + up = cv2.imread("cv23_lab1_part12_material/up.png") + up = cv2.cvtColor(up, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/up.png", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 2.5 + theta = 0.05 + + blobs = BoxFilters(gray, sigma, theta) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-ii-up.jpg") + + # play around with the parameters + sigma = 2.5 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BoxLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(up, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-ii-up.jpg") + + cells = cv2.imread("cv23_lab1_part12_material/cells.jpg") + cells = cv2.cvtColor(cells, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/cells.jpg", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 3 + theta = 0.05 + + blobs = BoxFilters(gray, sigma, theta) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-ii-cells.jpg") + + # play around with the parameters + sigma = 3 + theta = 0.05 + scale = 1.1 + N = 8 + + blobs = BoxLaplacian(gray, sigma, theta, scale, N) + interest_points_visualization(cells, blobs, None) + plt.savefig(f"image-plots/blob-detection-multiscale-ii-cells.jpg") + +boxtest() +plt.show() diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/box_detection_utils.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/box_detection_utils.py new file mode 100644 index 0000000..7783b1f --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/box_detection_utils.py @@ -0,0 +1,98 @@ +import numpy as np +import time +from intro_utils import LogMetric +from intro_utils import InterestPointCoord + + +def IntegralImage(i): + # this definitely works + return np.cumsum(np.cumsum(i, axis=0), axis=1) + +def BoxDerivative(image, sigma): + def roi(ii, x, y, padw): + # rectangle of interest + # the input image is padded, otherwise the shifts + # would have peculiar results + + # therefore remeber to unpad in the end + + # take the whole integral image and move it around + # the area outside of the rectangle will cancel itself out + # leaving only the values inside the rectangle of interest + shiftx = int((x + 1)/2 - 1) + shifty = int((y + 1)/2 - 1) + + # this isolates the upper and lower line + upline = np.roll(ii, shifty + 1, axis=0) + loline = np.roll(ii, -shifty, axis=0) + + # this isolates the upper corners + uprigh = np.roll(upline, -shiftx, axis=1) + upleft = np.roll(upline, shiftx+1, axis=1) + + # this isolates the lower corners + downri = np.roll(loline, -shiftx, axis=1) + downle = np.roll(loline, shiftx+1, axis=1) + + result = upleft - uprigh + downri - downle + # unpad in the end + result = result[padw:-padw, padw:-padw] + return result + + n = int(2*np.ceil(3*sigma) + 1) + height = int(4*np.floor(n/6) + 1) + width = int(2*np.floor(n/6) + 1) + padding = 2 * width + + padded = np.pad(image, padding, 'reflect') + ii = IntegralImage(padded) + + # sum the middle rectangle x(-3) and then add the whole rectangle + # (0 -3 0) + (1 1 1) = (1 -2 1) + lxx = -3*(roi(ii, width, height, padding)) + roi(ii, 3*width, height, padding) + lyy = -3*(roi(ii, height, width, padding)) + roi(ii, height, 3*width, padding) + + # the xy derivative requires a little special handling + smallbox = roi(ii, width, width, padding) + padded = np.pad(smallbox, padding, 'reflect') + shiftv = int((width-1)/2 + 1) + + ul = np.roll(padded, [shiftv, shiftv], axis=(0, 1)) + ur = np.roll(padded, [-shiftv, shiftv], axis=(0, 1)) + dl = np.roll(padded, [shiftv, -shiftv], axis=(0, 1)) + dr = np.roll(padded, [-shiftv, -shiftv], axis=(0, 1)) + + lxy = ul + dr - ur - dl + lxy = lxy[padding:-padding, padding:-padding] + + return (lxx, lxy, lyy) + +def BoxFilters(image, sigma, theta): + lxx, lxy, lyy = BoxDerivative(image, sigma) + r = lxx*lyy - (0.9*lxy)**2 + indices = InterestPointCoord(r, sigma, theta) + scale = sigma*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + return blobs + +def BoxLaplacian(image, sigma, theta, scale, N): + scales = [scale**i for i in list(range(N))] + sigmas = [scale * sigma for scale in scales] + + gradsxx = [] + gradsyy = [] + blobs_per_scale = [] + for s in sigmas: + lxx, lxy, lyy = BoxDerivative(image, s) + r = lxx*lyy - (0.9*lxy)**2 + indices = InterestPointCoord(r, s, theta) + scale = s*np.ones((indices.shape[0], 1)) + blobs = np.concatenate((indices, scale), axis=1) + + gradsxx.append(lxx) + gradsyy.append(lyy) + blobs_per_scale.append(blobs) + + grads = list(zip(scales, gradsxx, gradsyy)) + logs = [(s**2)*np.abs(xx + yy) for (s, xx, yy) in grads] + return LogMetric(logs, blobs_per_scale, N) diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/corner_detection.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/corner_detection.py new file mode 100644 index 0000000..2531c1d --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/corner_detection.py @@ -0,0 +1,27 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from cv23_lab1_part2_utils import interest_points_visualization + +# TESTED AND WORKING + +def cornertest(): + kyoto = cv2.imread("cv23_lab1_part12_material/kyoto_edges.jpg") + kyoto = cv2.cvtColor(kyoto, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/kyoto_edges.jpg", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + corners = CornerDetection(gray, 2, 2.5, 0.005, 0.1) + interest_points_visualization(kyoto, corners, None) + plt.savefig(f"image-plots/corner-detection.jpg") + + # play around with the parameters + corners = HarrisLaplacian(gray, 2, 2.5, 0.005, 0.1, 1.1, 6) + interest_points_visualization(kyoto, corners, None) + plt.savefig(f"image-plots/corner-detection-multiscale.jpg") + +cornertest() +plt.show() diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/corner_detection_utils.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/corner_detection_utils.py new file mode 100644 index 0000000..76f0e81 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/corner_detection_utils.py @@ -0,0 +1,82 @@ +import cv2 +import numpy as np +from intro_utils import myfilter +from intro_utils import smooth_gradient +from intro_utils import InterestPointCoord +from intro_utils import LogMetric +import matplotlib.pyplot as plt + +def CornerDetection(image, sigma, rho, theta, k): + # Keep in mind that the image is smoothed + # by default in the criterion function. + # r = CornerCriterion(image, sigma, rho, k) + + # calculate the gradient on both directions + gradx, grady = smooth_gradient(image, sigma, 1) + # calculate whatevere these elements are + Gr = myfilter(rho, "gaussian") + j1 = cv2.filter2D(gradx * gradx, -1, Gr) + j2 = cv2.filter2D(gradx * grady, -1, Gr) + j3 = cv2.filter2D(grady * grady, -1, Gr) + + # efficient way to calculate the eigenvalues + temp = j1 + j3 + lplus = 1/2*(temp + np.sqrt( (j1 - j3)**2 + 4*j2**2)) + lminus = temp - lplus + + fig, axs = plt.subplots(1,2) + axs[0].imshow(lminus, cmap='gray') + axs[0].set_title("l- eigenvalue") + axs[1].imshow(lplus, cmap='gray') + axs[1].set_title("l+ eigenvalue") + plt.show(block=False) + plt.pause(0.01) + plt.savefig("image-plots/corner-detection-eigenvalues.jpg") + + # calculate the cornerness criterion + r = lplus * lminus - k*((lplus + lminus)**2) + + indices = InterestPointCoord(r, sigma, theta) + scale = sigma*np.ones((indices.shape[0], 1)) + corners = np.concatenate((indices, scale), axis=1) + + return corners + +def HarrisLaplacian(image, sigma, rho, theta, k, scale, N): + # Multiscale Corner Detection + scales = [scale**i for i in list(range(N))] + sigmas = [scale * sigma for scale in scales] + rhos = [scale * rho for scale in scales] + params = list(zip(sigmas, rhos)) + + gradsxx = [] + gradsyy = [] + corners_per_scale = [] + for (s, r) in params: + # calculate the gradient on both directions + gradx, grady, gradxx, _, gradyy = smooth_gradient(image, s, 3) + + # calculate whatevere these elements are + Gr = myfilter(r, "gaussian") + j1 = cv2.filter2D(gradx * gradx, -1, Gr) + j2 = cv2.filter2D(gradx * grady, -1, Gr) + j3 = cv2.filter2D(grady * grady, -1, Gr) + + # efficient way to calculate the eigenvalues + temp = j1 + j3 + lplus = 1/2*(temp + np.sqrt( (j1 - j3)**2 + 4*j2**2)) + lminus = temp - lplus + # calculate the cornerness criterion + r = lplus * lminus - k*((lplus + lminus)**2) + + indices = InterestPointCoord(r, s, theta) + scale = s*np.ones((indices.shape[0], 1)) + corners = np.concatenate((indices, scale), axis=1) + + gradsxx.append(gradxx) + gradsyy.append(gradyy) + corners_per_scale.append(corners) + + grads = list(zip(scales, gradsxx, gradsyy)) + logs = [(s**2)*np.abs(xx + yy) for (s, xx, yy) in grads] + return LogMetric(logs, corners_per_scale, N) diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/cv23_lab1_part2_utils.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/cv23_lab1_part2_utils.py new file mode 100644 index 0000000..f8e5409 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/cv23_lab1_part2_utils.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +import sys +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.patches import Circle + +def interest_points_visualization(I_, kp_data_, ax=None): + ''' + Plot keypoints chosen by detectos on image. + Args: + I_: Image (if colored, make sure it is in RGB and not BGR). + kp_data_: Nx3 array, as described in assignment. + ax: Matplotlib axis to plot on (if None, a new Axes object is created). + Returns: + ax: Matplotlib axis where the image was plotted. + ''' + try: + I = np.array(I_) + kp_data = np.array(kp_data_) + except: + print('Conversion to numpy arrays failed, check if the inputs (image and keypoints) are in the required format.') + exit(2) + + try: + assert(len(I.shape) == 2 or (len(I.shape) == 3 and I.shape[2] == 3)) + except AssertionError as e: + print('interest_points_visualization: Image must be either a 2D matrix or a 3D matrix with the last dimension having size equal to 3.', file=sys.stderr) + exit(2) + + try: + assert(len(kp_data.shape) == 2 and kp_data.shape[1] == 3) + except AssertionError as e: + print('interest_points_visualization: kp_data must be a 2D matrix with 3 columns.', file=sys.stderr) + exit(2) + + if ax is None: + _, ax = plt.subplots() + + ax.set_aspect('equal') + ax.imshow(I) + ax.tick_params(bottom=False, left=False, labelbottom=False, labelleft=False) + + for i in range(len(kp_data)): + x, y, sigma = kp_data[i] + circ = Circle((x, y), 3*sigma, edgecolor='black', fill=False, linewidth=1) + ax.add_patch(circ) + + return ax + +def disk_strel(n): + ''' + Return a structural element, which is a disk of radius n. + ''' + r = int(np.round(n)) + d = 2*r+1 + x = np.arange(d) - r + y = np.arange(d) - r + x, y = np.meshgrid(x,y) + strel = x**2 + y**2 <= r**2 + return strel.astype(np.uint8) diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_intro.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_intro.py new file mode 100644 index 0000000..8b6b4a9 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_intro.py @@ -0,0 +1,60 @@ +import matplotlib.pyplot as plt +import numpy as np +import cv2 +from intro_utils import getstd +from edge_detection_utils import EdgeDetect +from edge_detection_utils import QualityMetric + +# TESTED AND WORKING + +def edgedetectintro(): + # read the image, convert to gray scale and normalize it + image = cv2.imread("cv23_lab1_part12_material/edgetest_23.png", cv2.IMREAD_GRAYSCALE) + image = image.astype(np.float64)/image.max() + + fig, axs = plt.subplots(1,1) + axs.imshow(image, cmap='gray') + axs.set_title("Original Image") + plt.show(block=False) + plt.pause(0.01) + + # add noise to the images. 10db and 20db + # in the psnr context, less dBs equals more noise + image10db = image + np.random.normal(0, getstd(image, 10), image.shape) + image20db = image + np.random.normal(0, getstd(image, 20), image.shape) + + # Play around with sigma and theta in order to + # obtain the best results. + noised_images = [image10db, image20db] + sigma = [3, 1.5] + theta = [0.2, 0.2] + thetareal = 0.08 + + for index, img in enumerate(noised_images): + N1 = EdgeDetect(img, sigma[index], theta[index], "linear") + N2 = EdgeDetect(img, sigma[index], theta[index], "nonlinear") + + cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) + M = cv2.dilate(image, cross) - cv2.erode(image, cross) + T = ( M > thetareal ).astype(np.uint8) + + fig, axs = plt.subplots(2,2) + axs[0, 0].imshow(img, cmap='gray') + axs[0, 0].set_title("Noised Image") + axs[0, 1].imshow(N1, cmap='gray') + axs[0, 1].set_title("Linear edge detection") + axs[1, 0].imshow(N2, cmap='gray') + axs[1, 0].set_title("Non linear edge detection") + axs[1, 1].imshow(T, cmap='gray') + axs[1, 1].set_title("Actual Edges") + plt.show(block=False) + plt.pause(0.01) + plt.savefig(f"image-plots/edges-intro{index}.jpg") + + C = QualityMetric(T, N1) + print(f"Linear method: C[{index}] = {C}") + C = QualityMetric(T, N2) + print(f"Non linear method: C[{index}] = {C}") + +edgedetectintro() +plt.show() diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_real.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_real.py new file mode 100644 index 0000000..500f916 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_real.py @@ -0,0 +1,51 @@ +import numpy as np +import matplotlib.pyplot as plt +import cv2 +from edge_detection_utils import EdgeDetect +from edge_detection_utils import QualityMetric + +# TESTED AND WORKING + +def edgedetectreal(): + # read image and normalize it + kyoto = cv2.imread("cv23_lab1_part12_material/kyoto_edges.jpg", cv2.IMREAD_GRAYSCALE) + kyoto = kyoto.astype(np.float64)/kyoto.max() + + # play around with sigma and theta + # big sigma => much smoothing => not fine details + # big theta => less edges, small theta => many edges + + sigma = 0.3 + theta = 0.2 + thetareal = 0.23 + + N1 = EdgeDetect(kyoto, sigma, theta, "linear") + N2 = EdgeDetect(kyoto, sigma, theta, "nonlinear") + + # the non linear method gives the best results, + # therefore we name it D and continue our evaluation + D = N2 + cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) + M = cv2.dilate(kyoto, cross) - cv2.erode(kyoto, cross) + T = ( M > thetareal ).astype(np.uint8) + + fig, axs = plt.subplots(2,2) + axs[0, 0].imshow(kyoto, cmap='gray') + axs[0, 0].set_title("Gray Image") + axs[0, 1].imshow(T, cmap='gray') + axs[0, 1].set_title("Actual Edges") + axs[1, 0].imshow(N1, cmap='gray') + axs[1, 0].set_title("Linear edge detection") + axs[1, 1].imshow(N2, cmap='gray') + axs[1, 1].set_title("Non Linear edge detection") + plt.show(block=False) + plt.pause(0.01) + plt.savefig(f"image-plots/edges-real.jpg") + + C = QualityMetric(T, D) + print(f"The quality criterion of the linear edge detection is C = {C}") + C = QualityMetric(T, N1) + print(f"The quality criterion of the non linear edge detection is C = {C}") + +edgedetectreal() +plt.show() \ No newline at end of file diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_utils.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_utils.py new file mode 100644 index 0000000..9e01cdd --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/edge_detection_utils.py @@ -0,0 +1,57 @@ +import numpy as np +import cv2 +from intro_utils import myfilter +from intro_utils import my2dconv + +def EdgeDetect(image, sigma, theta, method): + if (not (method == "linear" or method == "nonlinear")): + print("Error: method has to be either \"linear\" or \"nonlinear\"") + exit(2) + + gaussf = myfilter(sigma, "gaussian") + smooth = cv2.filter2D(image, -1, gaussf) + cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) + if (method == "linear"): + # construct the laplacian of gaussian kernel + # and use it to filter the image + logfilter = myfilter(sigma, "log") + #imgloged = cv2.filter2D(image, -1, logfilter) + imgloged = my2dconv(image, logfilter) + elif (method == "nonlinear"): + # Perform morphological operations using + # the cross structuring element + imgloged = cv2.dilate(smooth, cross) + cv2.erode(smooth, cross) - 2*smooth + + # the imgloged variable is visible only if one of the if blocks + # get executed. hopefully, this always happens + L = imgloged + + # type uin8 is needed for compatibility with the + # dilate and erode functions. otherwise, the matrix's + # elements would have boolean type. + X = (L > 0).astype(np.uint8) + Y = (cv2.dilate(X, cross)) - (cv2.erode(X, cross)) + + gradx, grady = np.gradient(smooth) + grad = np.abs(gradx + 1j * grady) + D = ((Y == 1) & (grad > (theta * np.max(grad)))) + return D + +def QualityMetric(real, computed): + # use the following names for compatibility + # with the project's guide. + T = real + D = computed + DT = (D & T) + # the matrices are supposed to be boolean + # therefore the sum() functions counts the + # elements that are true / 1. + cardT = T.sum() + cardD = D.sum() + cardDT = DT.sum() + + prTD = cardDT/cardT + prDT = cardDT/cardD + + C = (prDT + prTD)/2 + return C diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells-bad.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells-bad.jpg new file mode 100644 index 0000000..3a1ccd2 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells-bad.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells-good.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells-good.jpg new file mode 100644 index 0000000..f541ad6 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells-good.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells.jpg new file mode 100644 index 0000000..cac4130 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-cells.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-ii-cells.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-ii-cells.jpg new file mode 100644 index 0000000..622d6c1 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-ii-cells.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-ii-up.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-ii-up.jpg new file mode 100644 index 0000000..fa1dd95 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-ii-up.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells-bad.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells-bad.jpg new file mode 100644 index 0000000..3c5a1fe Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells-bad.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells-good.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells-good.jpg new file mode 100644 index 0000000..bd8f704 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells-good.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells.jpg new file mode 100644 index 0000000..8faa5ad Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-cells.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-ii-cells.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-ii-cells.jpg new file mode 100644 index 0000000..efa9dbd Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-ii-cells.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-ii-up.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-ii-up.jpg new file mode 100644 index 0000000..dddd797 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-ii-up.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-up.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-up.jpg new file mode 100644 index 0000000..5415d1a Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-multiscale-up.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-up.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-up.jpg new file mode 100644 index 0000000..5bfcf33 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/blob-detection-up.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/cells-gray.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/cells-gray.jpg new file mode 100644 index 0000000..c8a85e8 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/cells-gray.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/cells.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/cells.jpg new file mode 100644 index 0000000..e9109b4 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/cells.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection-eigenvalues.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection-eigenvalues.jpg new file mode 100644 index 0000000..7e28a26 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection-eigenvalues.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection-multiscale.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection-multiscale.jpg new file mode 100644 index 0000000..a3ada30 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection-multiscale.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection.jpg new file mode 100644 index 0000000..f4e26d3 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/corner-detection.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-intro0.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-intro0.jpg new file mode 100644 index 0000000..6c120f5 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-intro0.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-intro1.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-intro1.jpg new file mode 100644 index 0000000..85d17b5 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-intro1.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-real.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-real.jpg new file mode 100644 index 0000000..a120276 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edges-real.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edgetest_23.png b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edgetest_23.png new file mode 100644 index 0000000..2632a72 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/edgetest_23.png differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/grad-comparison.png b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/grad-comparison.png new file mode 100644 index 0000000..0151224 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/grad-comparison.png differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/kyoto_edges.jpg b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/kyoto_edges.jpg new file mode 100644 index 0000000..2808a3d Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/kyoto_edges.jpg differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/up.png b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/up.png new file mode 100644 index 0000000..51e84d0 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image-plots/up.png differ diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/intro_utils.py b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/intro_utils.py new file mode 100644 index 0000000..43a7d87 --- /dev/null +++ b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/intro_utils.py @@ -0,0 +1,102 @@ +import cv2 +import numpy as np +from cv23_lab1_part2_utils import disk_strel + +def getpsnr(image, noisestd): + return 20*np.log10((np.max(image)-np.min(image))/noisestd) + +def getstd(image, psnr): + return (np.max(image)-np.min(image))/(10**(psnr/20)) + +def my2dconv(image, kernel): + ix, iy = image.shape + nx, ny = kernel.shape + result = np.zeros((ix + nx - 1, iy + ny - 1)) + padded = np.pad(image, [(nx//2, nx//2),(ny//2,ny//2)], mode='constant') + for i in range(nx//2, ix + nx//2): + for j in range(ny//2, iy + ny//2): + result[i,j] = np.sum(padded[i-nx//2:i+nx//2+1,j-ny//2:j+ny//2+1] * kernel) + return result[nx//2:ix+nx//2, ny//2:iy+ny//2] + +def myfilter(sigma, method): + if (not (method == "gaussian" or method == "log")): + print("Error: method has to be either \"gaussian\" or \"log\"") + exit(2) + n = int(2*np.ceil(3*sigma)+1) + gauss1D = cv2.getGaussianKernel(n, sigma) # Column vector + gauss2D = gauss1D @ gauss1D.T # Symmetric gaussian kernel + if (method == "gaussian"): + return gauss2D + laplacian = np.array([[0,1,0], + [1,-4,1], + [0,1,0]]) + # perform the convolution between the gaussian kernel + # and the laplacian, in order to create the log kernel + # for sake of demonstration, we use our own convolution + # but later on we use the cv2 implementation. + logkernel = my2dconv(gauss2D, laplacian) + return logkernel + +def smooth_gradient(image, sigma, deg): + # define the filters according to the arguments + Gs = myfilter(sigma, "gaussian") + # smoothen the image + smooth = cv2.filter2D(image, -1, Gs) + # calculate the gradient on both directions + gradx, grady = np.gradient(smooth) + if (deg==1): + return (gradx, grady) + elif (deg==2): + gradxx, gradxy = np.gradient(gradx) + _ , gradyy = np.gradient(grady) + return (gradxx, gradxy, gradyy) + elif (deg==3): + gradxx, gradxy = np.gradient(gradx) + _ , gradyy = np.gradient(grady) + return (gradx, grady, gradxx, gradxy, gradyy) + print("deg = 1 for (gradx, grady)") + print("deg = 2 for (gradxx, gradxy, gradyy)") + print("deg = 3 for (gradx, grady, gradxx, gradxy, gradyy)") + exit(2) + +def InterestPointCoord(r, sigma, theta): + # r is a previously evaluated criterion + # sigma is used for the size of the structure + # theta is a threshold + + # evaluate the following 2 conditions + # condition 1 + ns = 2*np.ceil(3*sigma) + 1 + bsq = disk_strel(ns) + cond1 = ( r == cv2.dilate(r, bsq) ) + # condition 2 + maxr = np.max(r) + cond2 = ( r > theta * maxr ) + # choose the pixels that satisfy both of them + # return their coordinates and their scale + x, y = np.where(cond1 & cond2) + # for compatibility with the utility function + # provided by the lab staff, the y coordinate + # has to come before the x coordinate + indices = np.column_stack((y,x)) + return indices + +def LogMetric(logs, itemsperscale, N): + # log((x,y), s) = (s^2)|Lxx((x,y),s) + Lyy((x,y),s)| + # returns the coordinates of the points that maximize + # the log metric in a neighborhood of 3 scales + # (prev scale), (curr scale), (next scale) + final = [] + for index, items in enumerate(itemsperscale): + logp = logs[max(index-1,0)] + logc = logs[index] + logn = logs[min(index+1,N-1)] + for triplet in items: + x = int(triplet[1]) + y = int(triplet[0]) + prev = logp[x,y] + curr = logc[x,y] + next = logn[x,y] + if (curr >= prev) and (curr >= next): + final.append(triplet) + return np.array(final) diff --git a/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/lab1_part12_report.pdf b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/lab1_part12_report.pdf new file mode 100644 index 0000000..03b06a9 Binary files /dev/null and b/lab1/part12/cv23_Lab1_Part12_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/lab1_part12_report.pdf differ diff --git a/lab1/part12/cv23_lab1_part12_material/cells.jpg b/lab1/part12/cv23_lab1_part12_material/cells.jpg new file mode 100644 index 0000000..e9109b4 Binary files /dev/null and b/lab1/part12/cv23_lab1_part12_material/cells.jpg differ diff --git a/lab1/cv23_lab1_part12_material/cv23_lab1.pdf b/lab1/part12/cv23_lab1_part12_material/cv23_lab1.pdf similarity index 100% rename from lab1/cv23_lab1_part12_material/cv23_lab1.pdf rename to lab1/part12/cv23_lab1_part12_material/cv23_lab1.pdf diff --git a/lab1/cv23_lab1_part12_material/cv23_lab1_part2_utils.py b/lab1/part12/cv23_lab1_part12_material/cv23_lab1_part2_utils.py similarity index 100% rename from lab1/cv23_lab1_part12_material/cv23_lab1_part2_utils.py rename to lab1/part12/cv23_lab1_part12_material/cv23_lab1_part2_utils.py diff --git a/lab1/part12/cv23_lab1_part12_material/edgetest_23.png b/lab1/part12/cv23_lab1_part12_material/edgetest_23.png new file mode 100644 index 0000000..2632a72 Binary files /dev/null and b/lab1/part12/cv23_lab1_part12_material/edgetest_23.png differ diff --git a/lab1/part12/cv23_lab1_part12_material/kyoto_edges.jpg b/lab1/part12/cv23_lab1_part12_material/kyoto_edges.jpg new file mode 100644 index 0000000..2808a3d Binary files /dev/null and b/lab1/part12/cv23_lab1_part12_material/kyoto_edges.jpg differ diff --git a/lab1/part12/cv23_lab1_part12_material/up.png b/lab1/part12/cv23_lab1_part12_material/up.png new file mode 100644 index 0000000..51e84d0 Binary files /dev/null and b/lab1/part12/cv23_lab1_part12_material/up.png differ diff --git a/lab1/part12/cv23_lab1_part2_utils.py b/lab1/part12/cv23_lab1_part2_utils.py new file mode 100644 index 0000000..f8e5409 --- /dev/null +++ b/lab1/part12/cv23_lab1_part2_utils.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +import sys +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.patches import Circle + +def interest_points_visualization(I_, kp_data_, ax=None): + ''' + Plot keypoints chosen by detectos on image. + Args: + I_: Image (if colored, make sure it is in RGB and not BGR). + kp_data_: Nx3 array, as described in assignment. + ax: Matplotlib axis to plot on (if None, a new Axes object is created). + Returns: + ax: Matplotlib axis where the image was plotted. + ''' + try: + I = np.array(I_) + kp_data = np.array(kp_data_) + except: + print('Conversion to numpy arrays failed, check if the inputs (image and keypoints) are in the required format.') + exit(2) + + try: + assert(len(I.shape) == 2 or (len(I.shape) == 3 and I.shape[2] == 3)) + except AssertionError as e: + print('interest_points_visualization: Image must be either a 2D matrix or a 3D matrix with the last dimension having size equal to 3.', file=sys.stderr) + exit(2) + + try: + assert(len(kp_data.shape) == 2 and kp_data.shape[1] == 3) + except AssertionError as e: + print('interest_points_visualization: kp_data must be a 2D matrix with 3 columns.', file=sys.stderr) + exit(2) + + if ax is None: + _, ax = plt.subplots() + + ax.set_aspect('equal') + ax.imshow(I) + ax.tick_params(bottom=False, left=False, labelbottom=False, labelleft=False) + + for i in range(len(kp_data)): + x, y, sigma = kp_data[i] + circ = Circle((x, y), 3*sigma, edgecolor='black', fill=False, linewidth=1) + ax.add_patch(circ) + + return ax + +def disk_strel(n): + ''' + Return a structural element, which is a disk of radius n. + ''' + r = int(np.round(n)) + d = 2*r+1 + x = np.arange(d) - r + y = np.arange(d) - r + x, y = np.meshgrid(x,y) + strel = x**2 + y**2 <= r**2 + return strel.astype(np.uint8) diff --git a/lab1/part12/edge_detection_intro.py b/lab1/part12/edge_detection_intro.py new file mode 100644 index 0000000..8b6b4a9 --- /dev/null +++ b/lab1/part12/edge_detection_intro.py @@ -0,0 +1,60 @@ +import matplotlib.pyplot as plt +import numpy as np +import cv2 +from intro_utils import getstd +from edge_detection_utils import EdgeDetect +from edge_detection_utils import QualityMetric + +# TESTED AND WORKING + +def edgedetectintro(): + # read the image, convert to gray scale and normalize it + image = cv2.imread("cv23_lab1_part12_material/edgetest_23.png", cv2.IMREAD_GRAYSCALE) + image = image.astype(np.float64)/image.max() + + fig, axs = plt.subplots(1,1) + axs.imshow(image, cmap='gray') + axs.set_title("Original Image") + plt.show(block=False) + plt.pause(0.01) + + # add noise to the images. 10db and 20db + # in the psnr context, less dBs equals more noise + image10db = image + np.random.normal(0, getstd(image, 10), image.shape) + image20db = image + np.random.normal(0, getstd(image, 20), image.shape) + + # Play around with sigma and theta in order to + # obtain the best results. + noised_images = [image10db, image20db] + sigma = [3, 1.5] + theta = [0.2, 0.2] + thetareal = 0.08 + + for index, img in enumerate(noised_images): + N1 = EdgeDetect(img, sigma[index], theta[index], "linear") + N2 = EdgeDetect(img, sigma[index], theta[index], "nonlinear") + + cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) + M = cv2.dilate(image, cross) - cv2.erode(image, cross) + T = ( M > thetareal ).astype(np.uint8) + + fig, axs = plt.subplots(2,2) + axs[0, 0].imshow(img, cmap='gray') + axs[0, 0].set_title("Noised Image") + axs[0, 1].imshow(N1, cmap='gray') + axs[0, 1].set_title("Linear edge detection") + axs[1, 0].imshow(N2, cmap='gray') + axs[1, 0].set_title("Non linear edge detection") + axs[1, 1].imshow(T, cmap='gray') + axs[1, 1].set_title("Actual Edges") + plt.show(block=False) + plt.pause(0.01) + plt.savefig(f"image-plots/edges-intro{index}.jpg") + + C = QualityMetric(T, N1) + print(f"Linear method: C[{index}] = {C}") + C = QualityMetric(T, N2) + print(f"Non linear method: C[{index}] = {C}") + +edgedetectintro() +plt.show() diff --git a/lab1/part12/edge_detection_real.py b/lab1/part12/edge_detection_real.py new file mode 100644 index 0000000..500f916 --- /dev/null +++ b/lab1/part12/edge_detection_real.py @@ -0,0 +1,51 @@ +import numpy as np +import matplotlib.pyplot as plt +import cv2 +from edge_detection_utils import EdgeDetect +from edge_detection_utils import QualityMetric + +# TESTED AND WORKING + +def edgedetectreal(): + # read image and normalize it + kyoto = cv2.imread("cv23_lab1_part12_material/kyoto_edges.jpg", cv2.IMREAD_GRAYSCALE) + kyoto = kyoto.astype(np.float64)/kyoto.max() + + # play around with sigma and theta + # big sigma => much smoothing => not fine details + # big theta => less edges, small theta => many edges + + sigma = 0.3 + theta = 0.2 + thetareal = 0.23 + + N1 = EdgeDetect(kyoto, sigma, theta, "linear") + N2 = EdgeDetect(kyoto, sigma, theta, "nonlinear") + + # the non linear method gives the best results, + # therefore we name it D and continue our evaluation + D = N2 + cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) + M = cv2.dilate(kyoto, cross) - cv2.erode(kyoto, cross) + T = ( M > thetareal ).astype(np.uint8) + + fig, axs = plt.subplots(2,2) + axs[0, 0].imshow(kyoto, cmap='gray') + axs[0, 0].set_title("Gray Image") + axs[0, 1].imshow(T, cmap='gray') + axs[0, 1].set_title("Actual Edges") + axs[1, 0].imshow(N1, cmap='gray') + axs[1, 0].set_title("Linear edge detection") + axs[1, 1].imshow(N2, cmap='gray') + axs[1, 1].set_title("Non Linear edge detection") + plt.show(block=False) + plt.pause(0.01) + plt.savefig(f"image-plots/edges-real.jpg") + + C = QualityMetric(T, D) + print(f"The quality criterion of the linear edge detection is C = {C}") + C = QualityMetric(T, N1) + print(f"The quality criterion of the non linear edge detection is C = {C}") + +edgedetectreal() +plt.show() \ No newline at end of file diff --git a/lab1/part12/edge_detection_utils.py b/lab1/part12/edge_detection_utils.py new file mode 100644 index 0000000..9e01cdd --- /dev/null +++ b/lab1/part12/edge_detection_utils.py @@ -0,0 +1,57 @@ +import numpy as np +import cv2 +from intro_utils import myfilter +from intro_utils import my2dconv + +def EdgeDetect(image, sigma, theta, method): + if (not (method == "linear" or method == "nonlinear")): + print("Error: method has to be either \"linear\" or \"nonlinear\"") + exit(2) + + gaussf = myfilter(sigma, "gaussian") + smooth = cv2.filter2D(image, -1, gaussf) + cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) + if (method == "linear"): + # construct the laplacian of gaussian kernel + # and use it to filter the image + logfilter = myfilter(sigma, "log") + #imgloged = cv2.filter2D(image, -1, logfilter) + imgloged = my2dconv(image, logfilter) + elif (method == "nonlinear"): + # Perform morphological operations using + # the cross structuring element + imgloged = cv2.dilate(smooth, cross) + cv2.erode(smooth, cross) - 2*smooth + + # the imgloged variable is visible only if one of the if blocks + # get executed. hopefully, this always happens + L = imgloged + + # type uin8 is needed for compatibility with the + # dilate and erode functions. otherwise, the matrix's + # elements would have boolean type. + X = (L > 0).astype(np.uint8) + Y = (cv2.dilate(X, cross)) - (cv2.erode(X, cross)) + + gradx, grady = np.gradient(smooth) + grad = np.abs(gradx + 1j * grady) + D = ((Y == 1) & (grad > (theta * np.max(grad)))) + return D + +def QualityMetric(real, computed): + # use the following names for compatibility + # with the project's guide. + T = real + D = computed + DT = (D & T) + # the matrices are supposed to be boolean + # therefore the sum() functions counts the + # elements that are true / 1. + cardT = T.sum() + cardD = D.sum() + cardDT = DT.sum() + + prTD = cardDT/cardT + prDT = cardDT/cardD + + C = (prDT + prTD)/2 + return C diff --git a/lab1/part12/intro_utils.py b/lab1/part12/intro_utils.py new file mode 100644 index 0000000..d687883 --- /dev/null +++ b/lab1/part12/intro_utils.py @@ -0,0 +1,101 @@ +import cv2 +import numpy as np +from cv23_lab1_part2_utils import disk_strel + +def getpsnr(image, noisestd): + return 20*np.log10((np.max(image)-np.min(image))/noisestd) + +def getstd(image, psnr): + return (np.max(image)-np.min(image))/(10**(psnr/20)) + +def my2dconv(image, kernel): + ix, iy = image.shape + nx, ny = kernel.shape + result = np.zeros((ix + nx - 1, iy + ny - 1)) + padded = np.pad(image, [(nx//2, nx//2),(ny//2,ny//2)], mode='constant') + for i in range(nx//2, ix + nx//2): + for j in range(ny//2, iy + ny//2): + result[i,j] = np.sum(padded[i-nx//2:i+nx//2+1,j-ny//2:j+ny//2+1] * kernel) + return result[nx//2:ix+nx//2, ny//2:iy+ny//2] + +def myfilter(sigma, method): + if (not (method == "gaussian" or method == "log")): + print("Error: method has to be either \"gaussian\" or \"log\"") + exit(2) + n = int(2*np.ceil(3*sigma)+1) + gauss1D = cv2.getGaussianKernel(n, sigma) # Column vector + gauss2D = gauss1D @ gauss1D.T # Symmetric gaussian kernel + if (method == "gaussian"): + return gauss2D + laplacian = np.array([[0,1,0], + [1,-4,1], + [0,1,0]]) + # and the laplacian, in order to create the log kernel + # for sake of demonstration, we use our own convolution + # but later on we use the cv2 implementation. + logkernel = my2dconv(gauss2D, laplacian) + return logkernel + +def smooth_gradient(image, sigma, deg): + # define the filters according to the arguments + Gs = myfilter(sigma, "gaussian") + # smoothen the image + smooth = cv2.filter2D(image, -1, Gs) + # calculate the gradient on both directions + gradx, grady = np.gradient(smooth) + if (deg==1): + return (gradx, grady) + elif (deg==2): + gradxx, gradxy = np.gradient(gradx) + _ , gradyy = np.gradient(grady) + return (gradxx, gradxy, gradyy) + elif (deg==3): + gradxx, gradxy = np.gradient(gradx) + _ , gradyy = np.gradient(grady) + return (gradx, grady, gradxx, gradxy, gradyy) + print("deg = 1 for (gradx, grady)") + print("deg = 2 for (gradxx, gradxy, gradyy)") + print("deg = 3 for (gradx, grady, gradxx, gradxy, gradyy)") + exit(2) + +def InterestPointCoord(r, sigma, theta): + # r is a previously evaluated criterion + # sigma is used for the size of the structure + # theta is a threshold + + # evaluate the following 2 conditions + # condition 1 + ns = 2*np.ceil(3*sigma) + 1 + bsq = disk_strel(ns) + cond1 = ( r == cv2.dilate(r, bsq) ) + # condition 2 + maxr = np.max(r) + cond2 = ( r > theta * maxr ) + # choose the pixels that satisfy both of them + # return their coordinates and their scale + x, y = np.where(cond1 & cond2) + # for compatibility with the utility function + # provided by the lab staff, the y coordinate + # has to come before the x coordinate + indices = np.column_stack((y,x)) + return indices + +def LogMetric(logs, itemsperscale, N): + # log((x,y), s) = (s^2)|Lxx((x,y),s) + Lyy((x,y),s)| + # returns the coordinates of the points that maximize + # the log metric in a neighborhood of 3 scales + # (prev scale), (curr scale), (next scale) + final = [] + for index, items in enumerate(itemsperscale): + logp = logs[max(index-1,0)] + logc = logs[index] + logn = logs[min(index+1,N-1)] + for triplet in items: + x = int(triplet[1]) + y = int(triplet[0]) + prev = logp[x,y] + curr = logc[x,y] + next = logn[x,y] + if (curr >= prev) and (curr >= next): + final.append(triplet) + return np.array(final) diff --git a/lab1/part12/timing/timing-blobs.py b/lab1/part12/timing/timing-blobs.py new file mode 100644 index 0000000..5f4499b --- /dev/null +++ b/lab1/part12/timing/timing-blobs.py @@ -0,0 +1,59 @@ +import cv2 +import time +import numpy as np +import matplotlib.pyplot as plt +from box_detection_utils import BoxFilters +from box_detection_utils import BoxLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian + +def timing(): + up = cv2.imread("cv23_lab1_part12_material/up.png") + up = cv2.cvtColor(up, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/up.png", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + sigma = 3.5 + theta = 0.5 + scale = 1.1 + N = 8 + + testrange = list(range(2, 10)) + testnum = len(testrange) + normal = np.zeros((testnum, 1)) + fast = np.zeros((testnum, 1)) + + for index, sigma in enumerate(testrange): + start = time.time() + _ = BlobDetection(gray, sigma, theta) + end = time.time() + #print(f"sigma = {sigma} : Uniscale Blob Detection (No Integral Image) = {end-start}") + normal[index] = end - start + + start = time.time() + _ = BoxFilters(gray, sigma, theta) + end = time.time() + #print(f"sigma = {sigma} : Uniscale Blob Detection (Integral Image) = {end-start}") + fast[index] = end - start + + # start = time.time() + # blobs = HessianLaplacian(gray, sigma, theta, scale, N) + # end = time.time() + # print(f"sigma = {sigma} : Multiscale Blob Detection (No Integral Image) = {end-start}") + # start = time.time() + # blobs = BoxLaplacian(gray, sigma, theta, scale, N) + # end = time.time() + # print(f"sigma = {sigma} : Multiscale Blob Detection (Integral Image) = {end-start}") + + fig = plt.figure() + plt.plot(testrange, normal, label="convolution") + plt.plot(testrange, fast, label="integral images") + plt.legend(loc="upper left") + fig.suptitle("Timing of blob detection methods") + plt.xlabel("sigma") + plt.ylabel("time (s)") + fig.savefig("image-plots/blob-comparison.png") + plt.show() + +timing() diff --git a/lab1/part12/timing/timing-gradients.py b/lab1/part12/timing/timing-gradients.py new file mode 100644 index 0000000..e8bb1ea --- /dev/null +++ b/lab1/part12/timing/timing-gradients.py @@ -0,0 +1,51 @@ +import cv2 +import time +import numpy as np +import matplotlib.pyplot as plt +from intro_utils import smooth_gradient +from intro_utils import smooth_gradient2 +from box_detection_utils import BoxDerivative + +def timing(): + up = cv2.imread("cv23_lab1_part12_material/up.png") + up = cv2.cvtColor(up, cv2.COLOR_BGR2RGB) + gray = cv2.imread("cv23_lab1_part12_material/up.png", cv2.IMREAD_GRAYSCALE) + gray = gray.astype(np.float64)/gray.max() + + # play around with the parameters + + testrange = list(range(2, 10)) + testnum = len(testrange) + normal = np.zeros((testnum, 1)) + manual = np.zeros((testnum, 1)) + fast = np.zeros((testnum, 1)) + + for index, sigma in enumerate(testrange): + start = time.time() + _, _, _ = smooth_gradient(gray, sigma, 2) + end = time.time() + normal[index] = end - start + #print(f"manual convolution is {end - start}") + start = time.time() + _, _, _ = smooth_gradient2(gray, sigma, 2) + end = time.time() + manual[index] = end - start + #print(f"cv2 filter2D is {end - start}") + start = time.time() + _, _, _ = BoxDerivative(gray, sigma) + end = time.time() + fast[index] = end - start + #print(f"box derivative is {end - start}") + + fig = plt.figure() + plt.plot(testrange, normal, label="manual convolution") + plt.plot(testrange, manual, label="filter2D convolution") + plt.plot(testrange, fast, label="box derivative") + plt.legend(loc="upper left") + fig.suptitle("Timing of gradient computation methods") + plt.xlabel("sigma") + plt.ylabel("time (s)") + fig.savefig("image-plots/grad-comparison.png") + plt.show() + +timing() \ No newline at end of file diff --git a/lab1/part3/Fold_Indices.mat b/lab1/part3/Fold_Indices.mat new file mode 100644 index 0000000..7588f42 Binary files /dev/null and b/lab1/part3/Fold_Indices.mat differ diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification.py b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification.py new file mode 100644 index 0000000..9f4a527 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification.py @@ -0,0 +1,72 @@ +import os +import sys +sys.path.append('../part12') +import numpy as np + +from cv23_lab1_part3_utils import featuresSURF +from cv23_lab1_part3_utils import featuresHOG +from cv23_lab1_part3_utils import FeatureExtraction +from cv23_lab1_part3_utils import createTrainTest +from cv23_lab1_part3_utils import BagOfWords +from cv23_lab1_part3_utils import svm +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from box_detection_utils import BoxLaplacian + +# define descriptors and detectors +# also define their names in order to +# accomodate easier file creation +descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)] +detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05), + lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6), + lambda i: BlobDetection(i, 2, 0.005), + lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6), + lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)] +descriptor_names = ["featuresSURF", "featuresHOG"] +detector_names = ["CornerDetection", "HarrisLaplacian", "BlobDetection", "HessianLaplacian", "BoxLaplacian"] +detector_descriptor = [(detector, descriptor) + for detector in detectors + for descriptor in descriptors] +detector_descriptor_names = [(detector, descriptor) + for detector in detector_names + for descriptor in descriptor_names] + +if __name__ == '__main__': + functions_and_files = list(zip(detector_descriptor, files)) + if os.listdir("./features") == []: + files = ["./features/"+detector+'_'+descriptor+".txt" + for detector in detector_names + for descriptor in descriptor_names] + for name in files: + os.mknod(name) + # this takes around 20 minutes + features_list = [FeatureExtraction(detector, descriptor, saveFile=store) + for ((detector, descriptor), store) in functions_and_files] + else: + # this is instant provided that the files exist + features_list = [FeatureExtraction(detector, descriptor, loadFile=store) + for ((detector, descriptor), store) in functions_and_files] + + results = [] + for index, feats in enumerate(features_list): + accs = [] + for k in range(5): + # Split into a training set and a test set. + data_train, label_train, data_test, label_test = createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = BagOfWords(data_train, data_test) + # print(BOF_tr.shape, BOF_ts.shape) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + + detector, descriptor = detector_descriptor_names[index] + results.append(f"{detector}, {descriptor} :\t{100.0*np.mean(accs):.3f}\n") + + with open("mean_acc_bovw_results_test.txt", 'w') as file: + for result in results: + file.write(result) diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification_original.py b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification_original.py new file mode 100644 index 0000000..16fa884 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification_original.py @@ -0,0 +1,78 @@ +import os +from image_classification_original_utils import detector_descriptor +from image_classification_original_utils import detector_names +from image_classification_original_utils import descriptor_names +from image_classification_original_utils import detector_descriptor_names +from image_classification_original_utils import myFastBagOfVisualWords +from cv23_lab1_part3_utils import FeatureExtraction +from cv23_lab1_part3_utils import createTrainTest +from cv23_lab1_part3_utils import svm + +if __name__ == '__main__': + functions_and_files = list(zip(detector_descriptor, files)) + if os.listdir("./features") == []: + files = ["./features/"+detector+'_'+descriptor+".txt" + for detector in detector_names + for descriptor in descriptor_names] + for name in files: + os.mknod(name) + # this takes around 20 minutes + features_list = [FeatureExtraction(detector, descriptor, saveFile=store) + for ((detector, descriptor), store) in functions_and_files] + else: + # this is instant provided that the files exist + # otherwise it fails + features_list = [FeatureExtraction(detector, descriptor, loadFile=store) + for ((detector, descriptor), store) in functions_and_files] + + # this takes close to an hour + # perhaps the precompiled version uses less clusters and + # less max_iterations? I don't know. + results = [] + for index, feats in enumerate(features_list): + accs = [] + for k in range(5): + # Split into a testing set and a test set. + data_train, label_train, data_test, label_test = createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = myFastBagOfVisualWords(data_train, data_test, clusters=1000, maxiter=300) + # Perform Kmeans to find centroids for clusters. + #BOF_tr, BOF_ts = BagOfWords(data_train, data_test) + print(BOF_tr.shape, BOF_ts.shape) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + detector, descriptor = detector_descriptor_names[index] + results.append(f"{detector}, {descriptor} :\t{100.0*np.mean(accs):.3f}\n") + with open("mean_acc_mybovw_1000_results.txt", 'w') as file: + for result in results: + file.write(result) + + # This is perhaps a little bit faster. It takes + # around 30 minutes instead of 60. The number of iterations + # do not seem to make it much better. Increasing + # the tolerance makes it a bit faster, but the + # accuracy is also slightly decreased. + results = [] + for index, feats in enumerate(features_list): + accs = [] + for k in range(5): + # Split into a testing set and a test set. + data_train, label_train, data_test, label_test = createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = myFastBagOfVisualWords(data_train, data_test, clusters=500, maxiter=100) + # Perform Kmeans to find centroids for clusters. + #BOF_tr, BOF_ts = BagOfWords(data_train, data_test) + #print(BOF_tr.shape, BOF_ts.shape) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + detector, descriptor = detector_descriptor_names[index] + results.append(f"{detector}, {descriptor} :\t{100.0*np.mean(accs):.3f}\n") + with open("mean_acc_mybovw_500_results.txt", 'w') as file: + for result in results: + file.write(result) \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification_original_utils.py b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification_original_utils.py new file mode 100644 index 0000000..8dc3049 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_classification_original_utils.py @@ -0,0 +1,89 @@ +import sys +sys.path.append('../part12') +import numpy as np +from scipy.spatial.distance import cdist +from sklearn.cluster import KMeans + +from cv23_lab1_part3_utils import featuresSURF +from cv23_lab1_part3_utils import featuresHOG +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from box_detection_utils import BoxLaplacian + + +# define descriptors and detectors +# also define their names in order to +# accomodate easier file creation +descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)] +detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05), + lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6), + lambda i: BlobDetection(i, 2, 0.005), + lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6), + lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)] +descriptor_names = ["featuresSURF", "featuresHOG"] +detector_names = ["CornerDetection", "HarrisLaplacian", "BlobDetection", "HessianLaplacian", "BoxLaplacian"] +detector_descriptor = [(detector, descriptor) + for detector in detectors + for descriptor in descriptors] +detector_descriptor_names = [(detector, descriptor) + for detector in detector_names + for descriptor in descriptor_names] + +# THIS FUNCTION IS DEFINED FOR EDUCATIONAL PURPOSES +# IT IS NOT USED BECAUSE IT IS EXTREMELY SLOW +def kmeans(X, k, max_iters=100): + # X is the input data + # k is the number of clusters to form + # max_iters is the maximum number of iterations allowed + # returns the centroids and their labels + + n_samples, _ = X.shape + + # Initialize the cluster centroids randomly + centroids = X[np.random.choice(n_samples, size=k, replace=False)] + + for _ in range(max_iters): + # Assign each data point to the nearest cluster centroid + distances = np.linalg.norm(X[:, np.newaxis, :] - centroids, axis=-1) # shape (n_samples, k) + labels = np.argmin(distances, axis=-1) # shape (n_samples,) + + # Update the cluster centroids as the mean of the data points in each cluster + for i in range(k): + mask = (labels == i) + if np.sum(mask) > 0: + centroids[i] = np.mean(X[mask], axis=0) + + return centroids, labels + + +def myFastBagOfVisualWords(train, test, clusters=500, maxiter=100): + train_feature = np.concatenate(train, axis=0) + #test_feature = np.concatenate(test, axis=0) + + # Set the number of clusters (visual words) + # you can choose random number of clusters + # clusters = random.randint(500, 2000) + # clusters = 1000 # You can change this value + + # Perform k-means clustering + kmeans = KMeans(n_clusters=clusters, random_state=0, max_iter=maxiter, tol=0.001).fit(train_feature) + + # Function to compute the BoVW representation for a set of images + def compute_bovw(feature_set): + bovw_set = [] + for features in feature_set: + distances = cdist(features, kmeans.cluster_centers_, metric='euclidean') + labels = np.argmin(distances, axis=-1) + counts = np.bincount(labels, minlength=clusters) + l2norm = np.sqrt(np.sum(counts * counts)) + bovw = counts / l2norm + bovw_set.append(bovw) + return np.array(bovw_set) + + # Compute the BoVW representation for the training and testing sets + train_bovw = compute_bovw(train) + test_bovw = compute_bovw(test) + + return train_bovw, test_bovw diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_matching.py b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_matching.py new file mode 100644 index 0000000..7a83bb2 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/image_matching.py @@ -0,0 +1,65 @@ +import sys +sys.path.append('../part12') +import numpy as np + +from cv23_lab1_part3_utils import featuresSURF +from cv23_lab1_part3_utils import featuresHOG +from cv23_lab1_part3_utils import matching_evaluation +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from box_detection_utils import BoxLaplacian + + +# define descriptors and detectors +# also define their names in order to +# accomodate easier file creation +descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)] +detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05), + lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6), + lambda i: BlobDetection(i, 2, 0.005), + lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6), + lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)] +descriptor_names = ["featuresSURF", "featuresHOG"] +detector_names = ["CornerDetection", "HarrisLaplacian", "BlobDetection", "HessianLaplacian", "BoxLaplacian"] +detector_descriptor = [(detector, descriptor) + for detector in detectors + for descriptor in descriptors] + +if __name__ == '__main__': + # this takes around 1-2 minutes + avg_scale_errors_list = np.zeros((len(descriptors), len(detectors), 3)) + avg_theta_errors_list = np.zeros((len(descriptors), len(detectors), 3)) + for index, descriptor in enumerate(descriptors): + for jndex, detector in enumerate(detectors): + avg_scale_errors_list[index, jndex], avg_theta_errors_list[index, jndex] = matching_evaluation(detector, descriptor) + + np.set_printoptions(precision=3) + minim = np.mean(avg_scale_errors_list[0,0]) + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if minim > np.mean(avg_scale_errors_list[index, jndex]): + minim = np.mean(avg_scale_errors_list[index, jndex]) + bestpair = (descriptor, detector) + with open("../report/avg_scale_errors.txt", 'w') as file: + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if (descriptor, detector) == bestpair: + file.write(f"{descriptor}, {detector} :\t{avg_scale_errors_list[index, jndex]}\t BEST\n") + else: + file.write(f"{descriptor}, {detector} :\t{avg_scale_errors_list[index, jndex]}\t\n") + + minim = np.mean(avg_theta_errors_list[0,0]) + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if minim > np.mean(avg_scale_errors_list[index, jndex]): + minim = np.mean(avg_scale_errors_list[index, jndex]) + bestpair = (descriptor, detector) + with open("../report/avg_theta_errors.txt", 'w') as file: + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if (descriptor, detector) == bestpair: + file.write(f"{descriptor}, {detector} :\t{avg_theta_errors_list[index, jndex]}\t BEST\n") + else: + file.write(f"{descriptor}, {detector} :\t{avg_theta_errors_list[index, jndex]}\n") \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/lab1_part123_report.pdf b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/lab1_part123_report.pdf new file mode 100644 index 0000000..5cc92fc Binary files /dev/null and b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/lab1_part123_report.pdf differ diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BlobDetection_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..cf6d7b2 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BlobDetection_featuresHOG.txt @@ -0,0 +1 @@ +BlobDetection featuresHOG: 66.345 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BlobDetection_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..fcdb7a2 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BlobDetection_featuresSURF.txt @@ -0,0 +1 @@ +BlobDetection featuresSURF: 55.862 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BoxLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..a241a0a --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BoxLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +BoxLaplacian featuresHOG: 61.517 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BoxLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..8fa81be --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_BoxLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +BoxLaplacian featuresSURF: 53.379 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_CornerDetection_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..450b862 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_CornerDetection_featuresHOG.txt @@ -0,0 +1 @@ +CornerDetection featuresHOG: 63.724 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_CornerDetection_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..b791743 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_CornerDetection_featuresSURF.txt @@ -0,0 +1 @@ +CornerDetection featuresSURF: 51.862 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..e828dee --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresHOG: 66.483 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..b87d767 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresSURF: 59.310 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HessianLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..5a5d037 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HessianLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HessianLaplacian featuresHOG: 63.586 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HessianLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..66c5a7b --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_HessianLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HessianLaplacian featuresSURF: 57.103 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_results.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_results.txt new file mode 100644 index 0000000..dac2a55 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_results.txt @@ -0,0 +1,11 @@ +BlobDetection featuresHOG: 66.345 +BlobDetection featuresSURF: 55.862 +BoxLaplacian featuresHOG: 61.517 +BoxLaplacian featuresSURF: 53.379 +CornerDetection featuresHOG: 63.724 +CornerDetection featuresSURF: 51.862 +HarrisLaplacian featuresHOG: 66.483 +HarrisLaplacian featuresSURF: 59.310 +HessianLaplacian featuresHOG: 63.586 +HessianLaplacian featuresSURF: 57.103 + diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_results_sorted.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_results_sorted.txt new file mode 100644 index 0000000..d7b6c63 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_bovw/mean_acc_results_sorted.txt @@ -0,0 +1,10 @@ +HarrisLaplacian featuresHOG: 66.483 +BlobDetection featuresHOG: 66.345 +CornerDetection featuresHOG: 63.724 +HessianLaplacian featuresHOG: 63.586 +BoxLaplacian featuresHOG: 61.517 +HarrisLaplacian featuresSURF: 59.310 +HessianLaplacian featuresSURF: 57.103 +BlobDetection featuresSURF: 55.862 +BoxLaplacian featuresSURF: 53.379 +CornerDetection featuresSURF: 51.862 diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..124c32b --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresHOG.txt @@ -0,0 +1 @@ +BlobDetection featuresHOG: 64.552 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..f8e5dcd --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresSURF.txt @@ -0,0 +1 @@ +BlobDetection featuresSURF: 54.345 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..5daf3c2 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +BoxLaplacian featuresHOG: 62.207 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..9670d9d --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +BoxLaplacian featuresSURF: 52.552 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..fa3caed --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresHOG.txt @@ -0,0 +1 @@ +CornerDetection featuresHOG: 61.379 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..f0977cd --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresSURF.txt @@ -0,0 +1 @@ +CornerDetection featuresSURF: 56.966 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..d6d6489 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresHOG: 65.103 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..ff9b7d4 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresSURF: 57.793 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..359bbd8 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HessianLaplacian featuresHOG: 65.517 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..213158e --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HessianLaplacian featuresSURF: 59.586 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_results.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_results.txt new file mode 100644 index 0000000..12bed9a --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_results.txt @@ -0,0 +1,11 @@ +BlobDetection featuresHOG: 64.552 +BlobDetection featuresSURF: 54.345 +BoxLaplacian featuresHOG: 62.207 +BoxLaplacian featuresSURF: 52.552 +CornerDetection featuresHOG: 61.379 +CornerDetection featuresSURF: 56.966 +HarrisLaplacian featuresHOG: 65.103 +HarrisLaplacian featuresSURF: 57.793 +HessianLaplacian featuresHOG: 65.517 +HessianLaplacian featuresSURF: 59.586 + diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt new file mode 100644 index 0000000..2af56f5 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt @@ -0,0 +1,10 @@ +HessianLaplacian featuresHOG: 65.517 +HarrisLaplacian featuresHOG: 65.103 +BlobDetection featuresHOG: 64.552 +BoxLaplacian featuresHOG: 62.207 +CornerDetection featuresHOG: 61.379 +HessianLaplacian featuresSURF: 59.586 +HarrisLaplacian featuresSURF: 57.793 +CornerDetection featuresSURF: 56.966 +BlobDetection featuresSURF: 54.345 +BoxLaplacian featuresSURF: 52.552 diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..42d7fad --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresHOG.txt @@ -0,0 +1 @@ +BlobDetection featuresHOG: 65.931 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..5b356a2 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresSURF.txt @@ -0,0 +1 @@ +BlobDetection featuresSURF: 53.655 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..b374c4a --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +BoxLaplacian featuresHOG: 65.931 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..cc74e39 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +BoxLaplacian featuresSURF: 54.483 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..5e31c8b --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresHOG.txt @@ -0,0 +1 @@ +CornerDetection featuresHOG: 64.690 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..21bc49e --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresSURF.txt @@ -0,0 +1 @@ +CornerDetection featuresSURF: 54.621 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..d3df9fe --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresHOG: 64.828 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..c9a3754 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresSURF: 58.207 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresHOG.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..7f25651 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HessianLaplacian featuresHOG: 64.690 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresSURF.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..4a930b9 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HessianLaplacian featuresSURF: 56.552 \ No newline at end of file diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_results.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_results.txt new file mode 100644 index 0000000..ea78b2e --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_results.txt @@ -0,0 +1,11 @@ +BlobDetection featuresHOG: 65.931 +BlobDetection featuresSURF: 53.655 +BoxLaplacian featuresHOG: 65.931 +BoxLaplacian featuresSURF: 54.483 +CornerDetection featuresHOG: 64.690 +CornerDetection featuresSURF: 54.621 +HarrisLaplacian featuresHOG: 64.828 +HarrisLaplacian featuresSURF: 58.207 +HessianLaplacian featuresHOG: 64.690 +HessianLaplacian featuresSURF: 56.552 + diff --git a/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt new file mode 100644 index 0000000..9820e46 --- /dev/null +++ b/lab1/part3/cv23_Lab1_Part3_AnastasiosStefanosAnagnostou_03119051_SpyridonPapadopoulos_03119058/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt @@ -0,0 +1,10 @@ +BlobDetection featuresHOG: 65.931 +BoxLaplacian featuresHOG: 65.931 +HarrisLaplacian featuresHOG: 64.828 +CornerDetection featuresHOG: 64.690 +HessianLaplacian featuresHOG: 64.690 +HarrisLaplacian featuresSURF: 58.207 +HessianLaplacian featuresSURF: 56.552 +CornerDetection featuresSURF: 54.621 +BoxLaplacian featuresSURF: 54.483 +BlobDetection featuresSURF: 53.655 diff --git a/lab1/part3/cv23_lab1_part3_material/.ipynb_checkpoints/part1-checkpoint.ipynb b/lab1/part3/cv23_lab1_part3_material/.ipynb_checkpoints/part1-checkpoint.ipynb new file mode 100644 index 0000000..e1dad00 --- /dev/null +++ b/lab1/part3/cv23_lab1_part3_material/.ipynb_checkpoints/part1-checkpoint.ipynb @@ -0,0 +1,796 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "64a2a063", + "metadata": {}, + "outputs": [], + "source": [ + "# -*- coding: utf-8 -*-\n", + "import numpy as np\n", + "import utils\n", + "import cv2\n", + "from cv2 import imread\n", + "from scipy import ndimage\n", + "from cv2 import erode as imerode\n", + "from cv2 import dilate as imdilate\n", + "from cv2 import filter2D\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib\n", + "# matplotlib.use('TkAgg')\n", + "\n", + "\n", + "def EdgeDetect(I, sigma, theta_edge, laplac_type='linear'):\n", + " \"\"\"\n", + " Step 1.2 - Function to detect edges of an Image\n", + " Args:\n", + " I: np.array of image\n", + " sigma: Variance of noise\n", + " theta_edge: Threshold Parameter\n", + " laplacian_approx: Parameter to determine LoG approximation\n", + " choices:\n", + " linear: Perform LoG convolution\n", + " morph: Use morphological filters\n", + " \"\"\"\n", + "\n", + " ''' Step 1.2.1 - Create Filters '''\n", + "\n", + " # --GS--: Cast to int\n", + " kernel_size = int(np.ceil(3 * sigma) * 2 + 1)\n", + " filter_size = (kernel_size, kernel_size)\n", + " LoG = utils.fspecial(name='laplacian_of_gaussian', shape=filter_size, sigma=sigma)\n", + " G_sigma = utils.fspecial(name='gaussian', shape=filter_size, sigma=sigma)\n", + "\n", + " ''' Create smoothened image '''\n", + " I_sigma = filter2D(I, -1, G_sigma)\n", + " if laplac_type == 'linear':\n", + " ''' Step 1.2.2a - L1 Approach'''\n", + " # --GS--: Both with filter2D\n", + " L = filter2D(I, -1, LoG)\n", + "\n", + " elif laplac_type == 'morph':\n", + " ''' Step 1.2.2b Morphological Filters Approach '''\n", + " L = imdilate(I_sigma, utils.MorphologicalFilters.FIVE_POINT_FILTER) + \\\n", + " imerode(I_sigma, utils.MorphologicalFilters.FIVE_POINT_FILTER) - \\\n", + " 2 * I_sigma\n", + "\n", + " ''' Detect crossings and apply thresholding '''\n", + " result = utils.filter_crossings(I_sigma, L,\n", + " utils.MorphologicalFilters.FIVE_POINT_FILTER,\n", + " theta_edge)\n", + "\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "24a57232", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ZC: 160950\n", + "ZC: 171521\n", + "ZC: 69914\n", + "ZC: 106357\n", + "Noisy image with PSNR 20dB, linear filter. C = 0.8833215342697562\n", + "Noisy image with PSNR 20dB, morphological filter. C = 0.9184587107548174\n", + "Noisy image with PSNR 10dB, linear filter. C = 0.6440459669039402\n", + "Noisy image with PSNR 10dB, morphological filter. C = 0.7424200870210262\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "THETA_REAL = 0.2\n", + "THETA_NOISY1L = 0.1\n", + "THETA_NOISY1M = 0.1\n", + "SIGMA_1 = 1.5\n", + "THETA_NOISY2L = 0.2\n", + "THETA_NOISY2M = 0.2\n", + "THETA_VENICE = 80\n", + "SIGMA_2 = 3\n", + "PSNR1 = 20\n", + "PSNR2 = 10\n", + "\n", + "np.set_printoptions(precision=3)\n", + "\n", + "# # Step 1.1.1: Open images\n", + "# --GS--: Changed flag for clarity\n", + "X = imread('images/edgetest_23.png', cv2.IMREAD_GRAYSCALE).astype(float)/255\n", + "\n", + "# Step 1.1.2 Add noise to images\n", + "# --GS--: Left as is, it is well written.\n", + "X_n1, sigma_1 = utils.imnoise(X, PSNR=PSNR1)\n", + "X_n2, sigma_2 = utils.imnoise(X, PSNR=PSNR2)\n", + "\n", + "# --GS--: Plotting, left as is\n", + "fig = plt.figure(1)\n", + "fig.suptitle('Images with and without noise')\n", + "ax = plt.subplot(131)\n", + "plt.imshow(X, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Original')\n", + "ax = plt.subplot(132)\n", + "plt.imshow(X_n1, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('PSNR = 20dB')\n", + "\n", + "ax = plt.subplot(133)\n", + "plt.imshow(X_n2, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('PSNR = 10dB')\n", + "plt.savefig('result_images/1.png')\n", + "\n", + "''' Step 1.2.1 - Create Filters '''\n", + "\n", + "''' Perform Edge Detection '''\n", + "fig = plt.figure(2)\n", + "fig.suptitle('Edge detection')\n", + "\n", + "''' Non noisy image '''\n", + "ax = plt.subplot(231)\n", + "plt.imshow(X, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Original Image')\n", + "\n", + "T = utils.boundary_operator(X, utils.MorphologicalFilters.FIVE_POINT_FILTER) > THETA_REAL\n", + "ax = plt.subplot(232)\n", + "plt.imshow(T, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Original Image Edges')\n", + "\n", + "''' Noisy images '''\n", + "# Noisy image 1\n", + "nimgL1 = EdgeDetect(X_n1, SIGMA_1, THETA_NOISY1L, 'linear')\n", + "nimgM1 = EdgeDetect(X_n1, SIGMA_1, THETA_NOISY1M, 'morph')\n", + "\n", + "nimgL2 = EdgeDetect(X_n2, SIGMA_2, THETA_NOISY2L, 'linear')\n", + "nimgM2 = EdgeDetect(X_n2, SIGMA_2, THETA_NOISY2M, 'morph')\n", + "\n", + "ax = plt.subplot(233)\n", + "plt.imshow(nimgL1, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Noisy image with PSNR 20dB, linear filter.')\n", + "\n", + "\n", + "\n", + "ax = plt.subplot(234)\n", + "plt.imshow(nimgM1, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Noisy image with PSNR 20dB, morphological filter.')\n", + "\n", + "\n", + "ax = plt.subplot(235)\n", + "plt.imshow(nimgL2, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Noisy image with PSNR 10dB, linear filter.')\n", + "\n", + "\n", + "ax = plt.subplot(236)\n", + "plt.imshow(nimgM2, cmap=plt.get_cmap('gray'))\n", + "ax.set_title('Noisy image with PSNR 10dB, morphological filter')\n", + "plt.savefig('result_images/2.png')\n", + "\n", + "''' Evaluate Quality of Edge Detector '''\n", + "print('Noisy image with PSNR 20dB, linear filter. C = {}'.format(utils.quality_factor(nimgL1, T)))\n", + "print('Noisy image with PSNR 20dB, morphological filter. C = {}'.format(utils.quality_factor(nimgM1, T)))\n", + "print('Noisy image with PSNR 10dB, linear filter. C = {}'.format(utils.quality_factor(nimgL2, T)))\n", + "print('Noisy image with PSNR 10dB, morphological filter. C = {}'.format(utils.quality_factor(nimgM2, T)))" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "64f98f12", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "''' Step 1.4.1 - Test on real image'''\n", + "venice = imread('images/kyoto_edges.jpg', 0)\n", + "fig = plt.figure(3)\n", + "fig.suptitle('Edge detection on real images')\n", + "ax = plt.subplot(121)\n", + "plt.imshow(venice, cmap=plt.get_cmap('gray'))\n", + "\n", + "ax = plt.subplot(122)\n", + "binary_venice = utils.boundary_operator(venice, utils.MorphologicalFilters.FIVE_POINT_FILTER) > 40\n", + "plt.imshow(binary_venice, cmap=plt.get_cmap('gray'))\n", + "\n", + "plt.imshow(binary_venice)\n", + "plt.savefig('result_images/japan.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "570e9a60", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "plt.imshow(binary_venice, cmap=plt.get_cmap('gray'))\n", + "plt.savefig('result_images/kyoto_edges_40.jpg')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "502b635b", + "metadata": {}, + "outputs": [], + "source": [ + "# -*- coding: utf-8 -*-\n", + "import cv2\n", + "from cv2 import imread, COLOR_BGR2RGB, COLOR_RGB2GRAY, cvtColor\n", + "from cv2 import filter2D\n", + "import numpy as np\n", + "import utils\n", + "from scipy.signal import fftconvolve as conv2\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib\n", + "# matplotlib.use('TkAgg')\n", + "\n", + "\n", + "import numpy.matlib\n", + "from cv20_lab1_part2_utils import interest_points_visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "b5517e4d", + "metadata": {}, + "outputs": [], + "source": [ + "def wrap_before_visualization(kp, scales):\n", + "\n", + " kp_final = []\n", + " if(len(kp.shape) == 2):\n", + " kp_points = np.argwhere(kp.T)\n", + " kp_final.append(np.concatenate([kp_points, scales*np.ones((len(kp_points),1))], axis=1))\n", + " else:\n", + " for i,s in enumerate(scales):\n", + " kp_points = np.argwhere(kp[:,:,i].T)\n", + " kp_final.append(np.concatenate([kp_points, s*np.ones((len(kp_points),1))], axis=1))\n", + "\n", + " return np.concatenate(kp_final, axis=0)\n", + "\n", + "def harris_stephens(I, sigma=2, rho=2.5, k=0.05, threshold=0.005,\n", + " box_filters=False, plot=False):\n", + "\n", + " G_r, _ = utils.get_gaussian_filter(rho)\n", + " G_s, s_kern_size = utils.get_gaussian_filter(sigma)\n", + " ''' Calculate Sigma and Rho Image '''\n", + "\n", + " # --GS--: Again, changed to filter2D, in order to have zero-padding\n", + " I_sigma = filter2D(I, -1, G_s)\n", + "\n", + " J = utils.structural_tensor(I_sigma, G_r)\n", + " structural_eigs = utils.structural_eigenvalues(*J)\n", + " if plot:\n", + " fig = plt.figure()\n", + " fig.suptitle('Multichannel Structural Eigenvalues for σ = {},'\n", + " 'ρ = {}'.format(sigma, rho))\n", + " ax = plt.subplot(121)\n", + " plt.imshow(structural_eigs[0])\n", + " plt.title('λ+')\n", + " ax = plt.subplot(122)\n", + " plt.imshow(structural_eigs[1])\n", + " plt.title('λ-')\n", + " corners = utils.cornerness_criterion(\n", + " utils.angle_criterion(structural_eigs, k),\n", + " s_kern_size, threshold, sigma=sigma)\n", + " return corners\n", + "\n", + "\n", + "def single_scale_blobs(I, sigma=2, threshold=0.05, plot=False,\n", + " box_filters=False):\n", + " # G_s, kern_size = utils.get_gaussian_filter(sigma)\n", + " # I_sigma = filter2D(I, -1, G_s)\n", + "\n", + " kern_size = 2*np.ceil(3*sigma)+1\n", + " if not box_filters:\n", + " hessian = utils.hessian_matrix(I, sigma)\n", + " det = np.linalg.det(hessian)\n", + " blobs = utils.cornerness_criterion(det, kern_size, threshold, sigma=sigma)\n", + " else:\n", + " blobs = utils.hessian_approx_criterion(I, sigma, threshold)\n", + " # Lxx, Lyy, Lxy = utils.hessian_approx(I, sigma)\n", + " # hessian = np.array([[Lxx, Lxy], [Lxy, Lyy]])\n", + " # hessian = hessian.transpose(2, 3, 0, 1)\n", + "\n", + "\n", + " return blobs\n", + "\n", + "\n", + "def multiscale_blobs(I, sigma_0=2, threshold=0.05, N=4, s=1.5, plot=False,\n", + " box_filters=False):\n", + "\n", + " scales = [s**i * sigma_0 for i in range(N)]\n", + " h, w = I.shape\n", + " blobs = np.empty([h, w, N], dtype=bool)\n", + " LoG_metric = np.empty([h, w, N])\n", + " for i, scale in enumerate(scales):\n", + " ch_blobs = single_scale_blobs(I, sigma=scale,\n", + " threshold=threshold,\n", + " box_filters=box_filters)\n", + "\n", + " blobs[:, :, i] = ch_blobs\n", + " ''' Calculate normalized LoG '''\n", + " # --GS--: Changed calculation here to be with actual Log\n", + " n = int(2*np.ceil(3*scale)+1)\n", + " LoG_filt = utils.fspecial('laplacian_of_gaussian', (n,n), sigma=scale)\n", + " # --GS--: Should this change for box filters?\n", + " LoG_metric[:, :, i] = scale**2 * np.abs(filter2D(I, -1, LoG_filt))\n", + "\n", + " for i, sigma in enumerate(scales):\n", + " if i == 0:\n", + " blobs[:, :, i] = blobs[:, :, i] & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i + 1])\n", + " elif i == len(scales) - 1:\n", + " blobs[:, :, i] = blobs[:, :, i] & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i - 1])\n", + " else:\n", + " blobs[:, :, i] = blobs[:, :, i] & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i - 1]) & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i + 1])\n", + " return blobs, scales\n", + "\n", + "\n", + "def harris_laplacian(I, sigma_0=2, rho_0=2.5, k=0.05, threshold=0.005, s=1.5,\n", + " N=4, figure=False, box_filters=False):\n", + " ''' Create differentiation and integration scales '''\n", + " diff_scales = [s**i * sigma_0 for i in range(N)]\n", + " int_scales = [s**i * rho_0 for i in range(N)]\n", + " corners = np.empty(shape=(I.shape[0], I.shape[1], N), dtype=bool)\n", + "\n", + " LoG_metric = np.empty(shape=(I.shape[0], I.shape[1], N))\n", + "\n", + " for i, (sigma, rho) in enumerate(zip(diff_scales, int_scales)):\n", + " corners[:,:,i] = harris_stephens(I, sigma, rho, k, threshold)\n", + "\n", + " ''' Calculate normalized LoG '''\n", + " # --GS--: Changed calculation here to be with actual Log\n", + " n = int(2*np.ceil(3*sigma)+1)\n", + " LoG_filt = utils.fspecial('laplacian_of_gaussian', (n,n), sigma=sigma)\n", + " # --GS--: Should this change for box filters?\n", + " LoG_metric[:, :, i] = sigma**2 * np.abs(filter2D(I, -1, LoG_filt))\n", + "\n", + " for i, sigma in enumerate(diff_scales):\n", + " if i == 0:\n", + " corners[:, :, i] = corners[:, :, i] & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i + 1])\n", + " elif i == len(diff_scales) - 1:\n", + " corners[:, :, i] = corners[:, :, i] & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i - 1])\n", + " else:\n", + " corners[:, :, i] = corners[:, :, i] & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i - 1]) & \\\n", + " (LoG_metric[:, :, i] >= LoG_metric[:, :, i + 1])\n", + "\n", + " return corners, diff_scales" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "54b5ed77", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "''' Parameters '''\n", + "# General parameters\n", + "R = 2.5 # variation of G_r\n", + "\n", + "# Angles detection\n", + "SIGMA = 2 # variation of G_s\n", + "K = 0.05 # constant for angle criterion\n", + "THETA_CORN = 0.01 # thresholding for cornerness criterion\n", + "s = 1.5 # scale factor\n", + "N = 4 # number of scales\n", + "\n", + "# Blobs detection\n", + "SIGMA_H = 2\n", + "MULTISCALE_SIGMA_H = SIGMA_H\n", + "THRESHOLD_H = 0.25 # thresholding for cornerness criterion\n", + "\n", + "# with box filter\n", + "THRESHOLD_BOX_H = THRESHOLD_H\n", + "\n", + "''' Read images '''\n", + "sunflowers = cvtColor(imread('images/kyoto_edges.jpg'), COLOR_BGR2RGB)\n", + "# balloons = cvtColor(imread('../image_ideas/blob/mars_cassini_crater_v2.png'), COLOR_BGR2RGB)\n", + "balloons = cvtColor(imread('images/cells.jpg'), COLOR_BGR2RGB)\n", + "#cells = cvtColor(imread('../image_ideas/blob/cell2.jpg'), COLOR_BGR2RGB)\n", + "\n", + "# --GS--: Changed to grayscale, also changed type\n", + "sunflowers_gray = cvtColor(sunflowers, COLOR_RGB2GRAY)\n", + "balloons_gray = cvtColor(balloons, COLOR_RGB2GRAY)\n", + "# cells_gray = cvtColor(cells, COLOR_RGB2GRAY)\n", + "\n", + "sunflowers_gray = sunflowers_gray.astype(float)/255\n", + "balloons_gray = balloons_gray.astype(float)/255\n", + "# cells_gray = cells_gray.astype(float)/255\n", + "\n", + "#Corners detector\n", + "\n", + "\n", + "# single scale\n", + "sunflowers_corners = harris_stephens(sunflowers_gray, SIGMA, R, K, THETA_CORN, plot=True)\n", + "balloons_corners = harris_stephens(balloons_gray, SIGMA, R, K, THETA_CORN, plot=True)\n", + "# cells_corners = harris_stephens(cells_gray, SIGMA, R, K, THETA_CORN, plot=True)\n", + "fig = plt.figure(1)\n", + "fig.suptitle('Harris-Stephens Corner Detection')\n", + "ax = plt.subplot(121)\n", + "interest_points_visualization(sunflowers, wrap_before_visualization(sunflowers_corners, SIGMA), ax=ax)\n", + "interest_points_visualization(sunflowers, wrap_before_visualization(sunflowers_corners, SIGMA))\n", + "plt.title('Detected corners in sunflowers19.jpg')\n", + "plt.savefig('result_images/corners1_0.005.jpg')\n", + "plt.close()\n", + "\n", + "ax = plt.subplot(122)\n", + "fig = plt.figure(1)\n", + "interest_points_visualization(balloons, wrap_before_visualization(balloons_corners, SIGMA))\n", + "plt.title('Detected corners in balloons19.jpg')\n", + "plt.savefig('result_images/corners2_0.005.jpg')\n", + "plt.close()\n", + "\n", + "# ax = plt.subplot(122)\n", + "# fig = plt.figure(2)\n", + "# interest_points_visualization(cells, wrap_before_visualization(cells_corners, SIGMA))\n", + "# plt.title('Detected corners in balloons19.jpg')\n", + "# plt.savefig('Corner_cells.jpg')\n", + "# plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "2b6b6a9f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"\\n# multiscale\\nballoons_multiscale_corners, balloons_diff_scales = harris_laplacian(balloons_gray, SIGMA, R, K, THETA_CORN, s, N)\\nsunflowers_multiscale_corners, sunflowers_diff_scales = harris_laplacian(sunflowers_gray, SIGMA, R, K, THETA_CORN, s, N)\\nfig = plt.figure(figsize=(15, 15))\\n#fig.suptitle('Harris-Laplacian Corner Detection')\\n#ax = plt.subplot(121)\\ninterest_points_visualization(sunflowers, wrap_before_visualization(sunflowers_multiscale_corners,\\n sunflowers_diff_scales))\\n\\nplt.savefig('result_images/multi_corners_1_0.005.jpg')\\nplt.close()\\n#plt.title('Detected corners in sunflowers19.jpg')\\n\\n#ax = plt.subplot(122)\\ninterest_points_visualization(balloons, wrap_before_visualization(balloons_multiscale_corners,\\n balloons_diff_scales))\\n#plt.title('Detected corners in balloons19.jpg')\\nplt.savefig('result_images/multi_corners_2_0.005.jpg')\\nplt.close()\\n\"" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''\n", + "# multiscale\n", + "balloons_multiscale_corners, balloons_diff_scales = harris_laplacian(balloons_gray, SIGMA, R, K, THETA_CORN, s, N)\n", + "sunflowers_multiscale_corners, sunflowers_diff_scales = harris_laplacian(sunflowers_gray, SIGMA, R, K, THETA_CORN, s, N)\n", + "fig = plt.figure(figsize=(15, 15))\n", + "#fig.suptitle('Harris-Laplacian Corner Detection')\n", + "#ax = plt.subplot(121)\n", + "interest_points_visualization(sunflowers, wrap_before_visualization(sunflowers_multiscale_corners,\n", + " sunflowers_diff_scales))\n", + "\n", + "plt.savefig('result_images/multi_corners_1_0.005.jpg')\n", + "plt.close()\n", + "#plt.title('Detected corners in sunflowers19.jpg')\n", + "\n", + "#ax = plt.subplot(122)\n", + "interest_points_visualization(balloons, wrap_before_visualization(balloons_multiscale_corners,\n", + " balloons_diff_scales))\n", + "#plt.title('Detected corners in balloons19.jpg')\n", + "plt.savefig('result_images/multi_corners_2_0.005.jpg')\n", + "plt.close()\n", + "'''" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "1d114f77", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Blobs detector\n", + "\n", + "# Single scale\n", + "fig = plt.figure(figsize=(15,15))\n", + "#fig.suptitle('One scale blob detection')\n", + "\n", + "sunflowers_blobs = single_scale_blobs(sunflowers_gray, sigma=SIGMA_H, threshold=THRESHOLD_H)\n", + "#ax = plt.subplot(121)\n", + "interest_points_visualization(sunflowers, wrap_before_visualization(sunflowers_blobs, SIGMA_H))\n", + "#plt.title('Blobs detected in sunflowers19.jpg')\n", + "fig.set_size_inches(10, 8)\n", + "plt.savefig('result_images/blobs_1.jpg', dpi=100)\n", + "plt.close()\n", + "\n", + "fig = plt.figure(figsize=(15,15))\n", + "balloons_blobs = single_scale_blobs(balloons_gray, sigma=SIGMA_H, threshold=THRESHOLD_H)\n", + "#ax = plt.subplot(122)\n", + "interest_points_visualization(balloons, wrap_before_visualization(balloons_blobs, SIGMA_H))\n", + "#plt.title('Blobs detected in balloons19.jpg')\n", + "fig.set_size_inches(10, 8)\n", + "plt.savefig('result_images/blobs_2.jpg', dpi=100)\n", + "plt.close()\n", + "\n", + "# # Multiscale\n", + "fig = plt.figure(figsize=(15,15))\n", + "#fig.suptitle('Multiscale blob detection (N=4)')\n", + "\n", + "sunflowers_multiscale_blobs, scales = multiscale_blobs(sunflowers_gray,\n", + " sigma_0=MULTISCALE_SIGMA_H,\n", + " threshold=THRESHOLD_H)\n", + "#ax = plt.subplot(121)\n", + "interest_points_visualization(sunflowers, wrap_before_visualization(sunflowers_multiscale_blobs, scales))\n", + "#plt.title('Blobs detected in sunflowers19.jpg')\n", + "fig.set_size_inches(10, 8)\n", + "plt.savefig('result_images/multi_blobs_1.jpg', dpi=100)\n", + "plt.close()\n", + "\n", + "balloons_multiscale_blobs, scales = multiscale_blobs(balloons_gray,\n", + " sigma_0=MULTISCALE_SIGMA_H,\n", + " threshold=THRESHOLD_H)\n", + "#ax = plt.subplot(122)\n", + "interest_points_visualization(balloons, wrap_before_visualization(balloons_multiscale_blobs, scales))\n", + "#plt.title('Blobs detected in balloons19.jpg')\n", + "fig.set_size_inches(10, 8)\n", + "plt.savefig('result_images/multi_blobs_2.jpg', dpi=100)\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "70ac15ee", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'utils'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_7181/966850981.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mcv23_lab1_part3_utils\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mp3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mcv23_lab1_part2\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mp2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m#import test as p3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mdetect_fun\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mI\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mp2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrap_before_visualization\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mp2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmultiscale_blobs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mI\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Documents/ComputerVision/LAB_1_2023/cv23_lab1_part3_material/cv23_lab1_part2.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mcv2\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mfilter2D\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mutils\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mscipy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msignal\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mfftconvolve\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mconv2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpyplot\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'utils'" + ] + } + ], + "source": [ + "import cv23_lab1_part3_utils as p3\n", + "import cv23_lab1_part2 as p2\n", + "#import test as p3\n", + "\n", + "detect_fun = lambda I: p2.wrap_before_visualization(*p2.multiscale_blobs(I))\n", + "desc_fun = p3.featuresHOG\n", + "\n", + "p3.matching_evaluation(detect_fun, desc_fun)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb16961d", + "metadata": {}, + "outputs": [], + "source": [ + "!python --version" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "51eeb11a", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "8f7329ba", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([0.0016287722451904533, 0.0017862250684174423, 0.0008604604273302808],\n", + " [0.05784271729631431, 0.09651336532673375, 0.09970917464548007])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "detect_fun = lambda I: p2.wrap_before_visualization(*p2.multiscale_blobs(I))\n", + "desc_fun = p3.featuresSURF\n", + "\n", + "p3.matching_evaluation(detect_fun, desc_fun)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a51bb682", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Time for feature extraction: 155.038\n", + "Mean accuracy for Harris Laplace with SURF descriptors: 60.000%\n", + "Time for feature extraction: 126.636\n", + "Mean accuracy for Harris Laplace with HOG descriptors: 61.379%\n", + "Time for feature extraction: 169.955\n", + "Mean accuracy for Hessian Laplace with SURF descriptors: 61.379%\n", + "Time for feature extraction: 170.150\n", + "Mean accuracy for Hessian Laplace with HOG descriptors: 62.897%\n", + "Time for feature extraction: 140.641\n", + "Mean accuracy for Boxfilters with SURF descriptors: 59.862%\n", + "Time for feature extraction: 117.396\n", + "Mean accuracy for Boxfilters with HOG descriptors: 63.586%\n" + ] + } + ], + "source": [ + "detectors = [\n", + " ('Harris Laplace', lambda I: p2.wrap_before_visualization(*p2.harris_laplacian(I, sigma_0=1.6, rho_0=2, k=0.005, threshold=0.01, s=1.4, N=4))),\n", + " ('Hessian Laplace', lambda I: p2.wrap_before_visualization(*p2.multiscale_blobs(I, sigma_0=1.6, threshold=0.01, s=1.4, N=4))),\n", + " ('Boxfilters', lambda I: p2.wrap_before_visualization(*p2.multiscale_blobs(I, sigma_0=1.6, threshold=0.01, s=1.4, N=4, box_filters=True))),\n", + "]\n", + "descriptors = [\n", + " ('SURF', p3.featuresSURF),\n", + " ('HOG', p3.featuresHOG)\n", + "]\n", + "\n", + "\n", + "for detect_name, detect_fun in detectors:\n", + " for desc_name, desc_fun in descriptors:\n", + " feats = p3.FeatureExtraction(detect_fun, desc_fun)\n", + " accs = []\n", + " for k in range(5):\n", + " data_train, label_train, data_test, label_test = p3.createTrainTest(feats, k)\n", + " BOF_tr, BOF_ts = p3.BagOfWords(data_train, data_test)\n", + " p, _, _ = p3.svm(BOF_tr, label_train, BOF_ts, label_test)\n", + " accs.append(p)\n", + "\n", + " print('Mean accuracy for {0:} with {1:} descriptors: {2:.3f}%'.format(detect_name, desc_name, 100.0*np.mean(accs)))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9bc70ff1", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lab1/part3/cv23_lab1_part3_material/example_classification.py b/lab1/part3/cv23_lab1_part3_material/example_classification.py new file mode 100644 index 0000000..8e170a4 --- /dev/null +++ b/lab1/part3/cv23_lab1_part3_material/example_classification.py @@ -0,0 +1,33 @@ +# Assuming detectors are in file "cv20_lab1_part2.py", replace with your filename. +import cv20_lab1_part3_utils as p3 +import cv20_lab1_part2 as p2 + +import numpy as np + +if __name__ == '__main__': + # Change with your own detectors here! + detect_fun = lambda I: p2.harrisLaplaceDetector(I, 2, 2.5, 0.05, 0.005, 1.5, 4) + + desc_fun = lambda I, kp: p3.featuresSURF(I,kp) + + # Extract features from the provided dataset. + feats = p3.FeatureExtraction(detect_fun, desc_fun) + + # If the above code takes too long, you can use the following extra parameters of Feature extraction: + # saveFile = : Save the extracted features in a file with the provided name. + # loadFile = : Load the extracted features from a given file (which MUST exist beforehand). + + + accs = [] + for k in range(5): + # Split into a training set and a test set. + data_train, label_train, data_test, label_test = p3.createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = p3.BagOfWords(data_train, data_test) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = p3.svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + + print('Mean accuracy for Harris-Laplace with SURF descriptors: {:.3f}%'.format(100.0*np.mean(accs))) diff --git a/lab1/part3/cv23_lab1_part3_material/test_matching_evaluation.py b/lab1/part3/cv23_lab1_part3_material/test_matching_evaluation.py new file mode 100644 index 0000000..5d534d5 --- /dev/null +++ b/lab1/part3/cv23_lab1_part3_material/test_matching_evaluation.py @@ -0,0 +1,18 @@ +# Assuming detectors are in file "cv20_lab1_part2.py", replace with your filename. +import cv20_lab1_part3_utils as p3 +import cv20_lab1_part2 as p2 + +if __name__ == '__main__': + # Here is a lambda which acts as a wrapper for detector function, e.g. harrisDetector. + # The detector arguments are, in order: image, sigma, rho, k, threshold. + detect_fun = lambda I: p2.harrisDetector(I, 2, 2.5, 0.05, 0.005) + + # You can use either of the following lines to extract features (HOG/SURF). + desc_fun = lambda I, kp: p3.featuresSURF(I,kp) + # desc_fun = lambda I, kp: p3.featuresHOG(I,kp) + + # Execute evaluation by providing the above functions as arguments + # Returns 2 1x3 arrays containing the errors + avg_scale_errors, avg_theta_errors = p3.matching_evaluation(detect_fun, desc_fun) + print('Avg. Scale Error for Image 1: {:.3f}'.format(avg_scale_errors[0])) + print('Avg. Theta Error for Image 1: {:.3f}'.format(avg_theta_errors[0])) diff --git a/lab1/part3/cv23_lab1_part3_utils.pyc b/lab1/part3/cv23_lab1_part3_utils.pyc new file mode 100644 index 0000000..edb5794 Binary files /dev/null and b/lab1/part3/cv23_lab1_part3_utils.pyc differ diff --git a/lab1/part3/features-trial/BlobDetection_featuresHOG.txt b/lab1/part3/features-trial/BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..3d02720 Binary files /dev/null and b/lab1/part3/features-trial/BlobDetection_featuresHOG.txt differ diff --git a/lab1/part3/features-trial/BlobDetection_featuresSURF.txt b/lab1/part3/features-trial/BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..2d5cff8 Binary files /dev/null and b/lab1/part3/features-trial/BlobDetection_featuresSURF.txt differ diff --git a/lab1/part3/features-trial/BoxLaplacian_featuresHOG.txt b/lab1/part3/features-trial/BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..fb254e5 Binary files /dev/null and b/lab1/part3/features-trial/BoxLaplacian_featuresHOG.txt differ diff --git a/lab1/part3/features-trial/BoxLaplacian_featuresSURF.txt b/lab1/part3/features-trial/BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..fcf77dc Binary files /dev/null and b/lab1/part3/features-trial/BoxLaplacian_featuresSURF.txt differ diff --git a/lab1/part3/features-trial/CornerDetection_featuresHOG.txt b/lab1/part3/features-trial/CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..86ee8da Binary files /dev/null and b/lab1/part3/features-trial/CornerDetection_featuresHOG.txt differ diff --git a/lab1/part3/features-trial/CornerDetection_featuresSURF.txt b/lab1/part3/features-trial/CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..1281d1e Binary files /dev/null and b/lab1/part3/features-trial/CornerDetection_featuresSURF.txt differ diff --git a/lab1/part3/features-trial/HarrisLaplacian_featuresHOG.txt b/lab1/part3/features-trial/HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..d3bba4f Binary files /dev/null and b/lab1/part3/features-trial/HarrisLaplacian_featuresHOG.txt differ diff --git a/lab1/part3/features-trial/HarrisLaplacian_featuresSURF.txt b/lab1/part3/features-trial/HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..3b52359 Binary files /dev/null and b/lab1/part3/features-trial/HarrisLaplacian_featuresSURF.txt differ diff --git a/lab1/part3/features-trial/HessianLaplacian_featuresHOG.txt b/lab1/part3/features-trial/HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..c2dd4da Binary files /dev/null and b/lab1/part3/features-trial/HessianLaplacian_featuresHOG.txt differ diff --git a/lab1/part3/features-trial/HessianLaplacian_featuresSURF.txt b/lab1/part3/features-trial/HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..4ed6f24 Binary files /dev/null and b/lab1/part3/features-trial/HessianLaplacian_featuresSURF.txt differ diff --git a/lab1/part3/features/BlobDetection_featuresHOG.txt b/lab1/part3/features/BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..aa96fff Binary files /dev/null and b/lab1/part3/features/BlobDetection_featuresHOG.txt differ diff --git a/lab1/part3/features/BlobDetection_featuresSURF.txt b/lab1/part3/features/BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..e9f2f18 Binary files /dev/null and b/lab1/part3/features/BlobDetection_featuresSURF.txt differ diff --git a/lab1/part3/features/BoxLaplacian_featuresHOG.txt b/lab1/part3/features/BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..6c77c20 Binary files /dev/null and b/lab1/part3/features/BoxLaplacian_featuresHOG.txt differ diff --git a/lab1/part3/features/BoxLaplacian_featuresSURF.txt b/lab1/part3/features/BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..c26c8f7 Binary files /dev/null and b/lab1/part3/features/BoxLaplacian_featuresSURF.txt differ diff --git a/lab1/part3/features/CornerDetection_featuresHOG.txt b/lab1/part3/features/CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..928c3d7 Binary files /dev/null and b/lab1/part3/features/CornerDetection_featuresHOG.txt differ diff --git a/lab1/part3/features/CornerDetection_featuresSURF.txt b/lab1/part3/features/CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..8aecf4a Binary files /dev/null and b/lab1/part3/features/CornerDetection_featuresSURF.txt differ diff --git a/lab1/part3/features/HarrisLaplacian_featuresHOG.txt b/lab1/part3/features/HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..1632215 Binary files /dev/null and b/lab1/part3/features/HarrisLaplacian_featuresHOG.txt differ diff --git a/lab1/part3/features/HarrisLaplacian_featuresSURF.txt b/lab1/part3/features/HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..540005b Binary files /dev/null and b/lab1/part3/features/HarrisLaplacian_featuresSURF.txt differ diff --git a/lab1/part3/features/HessianLaplacian_featuresHOG.txt b/lab1/part3/features/HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..7ee3af8 Binary files /dev/null and b/lab1/part3/features/HessianLaplacian_featuresHOG.txt differ diff --git a/lab1/part3/features/HessianLaplacian_featuresSURF.txt b/lab1/part3/features/HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..1d85fb6 Binary files /dev/null and b/lab1/part3/features/HessianLaplacian_featuresSURF.txt differ diff --git a/lab1/part3/image_classification.py b/lab1/part3/image_classification.py new file mode 100644 index 0000000..9f4a527 --- /dev/null +++ b/lab1/part3/image_classification.py @@ -0,0 +1,72 @@ +import os +import sys +sys.path.append('../part12') +import numpy as np + +from cv23_lab1_part3_utils import featuresSURF +from cv23_lab1_part3_utils import featuresHOG +from cv23_lab1_part3_utils import FeatureExtraction +from cv23_lab1_part3_utils import createTrainTest +from cv23_lab1_part3_utils import BagOfWords +from cv23_lab1_part3_utils import svm +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from box_detection_utils import BoxLaplacian + +# define descriptors and detectors +# also define their names in order to +# accomodate easier file creation +descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)] +detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05), + lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6), + lambda i: BlobDetection(i, 2, 0.005), + lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6), + lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)] +descriptor_names = ["featuresSURF", "featuresHOG"] +detector_names = ["CornerDetection", "HarrisLaplacian", "BlobDetection", "HessianLaplacian", "BoxLaplacian"] +detector_descriptor = [(detector, descriptor) + for detector in detectors + for descriptor in descriptors] +detector_descriptor_names = [(detector, descriptor) + for detector in detector_names + for descriptor in descriptor_names] + +if __name__ == '__main__': + functions_and_files = list(zip(detector_descriptor, files)) + if os.listdir("./features") == []: + files = ["./features/"+detector+'_'+descriptor+".txt" + for detector in detector_names + for descriptor in descriptor_names] + for name in files: + os.mknod(name) + # this takes around 20 minutes + features_list = [FeatureExtraction(detector, descriptor, saveFile=store) + for ((detector, descriptor), store) in functions_and_files] + else: + # this is instant provided that the files exist + features_list = [FeatureExtraction(detector, descriptor, loadFile=store) + for ((detector, descriptor), store) in functions_and_files] + + results = [] + for index, feats in enumerate(features_list): + accs = [] + for k in range(5): + # Split into a training set and a test set. + data_train, label_train, data_test, label_test = createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = BagOfWords(data_train, data_test) + # print(BOF_tr.shape, BOF_ts.shape) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + + detector, descriptor = detector_descriptor_names[index] + results.append(f"{detector}, {descriptor} :\t{100.0*np.mean(accs):.3f}\n") + + with open("mean_acc_bovw_results_test.txt", 'w') as file: + for result in results: + file.write(result) diff --git a/lab1/part3/image_classification_original.py b/lab1/part3/image_classification_original.py new file mode 100644 index 0000000..16fa884 --- /dev/null +++ b/lab1/part3/image_classification_original.py @@ -0,0 +1,78 @@ +import os +from image_classification_original_utils import detector_descriptor +from image_classification_original_utils import detector_names +from image_classification_original_utils import descriptor_names +from image_classification_original_utils import detector_descriptor_names +from image_classification_original_utils import myFastBagOfVisualWords +from cv23_lab1_part3_utils import FeatureExtraction +from cv23_lab1_part3_utils import createTrainTest +from cv23_lab1_part3_utils import svm + +if __name__ == '__main__': + functions_and_files = list(zip(detector_descriptor, files)) + if os.listdir("./features") == []: + files = ["./features/"+detector+'_'+descriptor+".txt" + for detector in detector_names + for descriptor in descriptor_names] + for name in files: + os.mknod(name) + # this takes around 20 minutes + features_list = [FeatureExtraction(detector, descriptor, saveFile=store) + for ((detector, descriptor), store) in functions_and_files] + else: + # this is instant provided that the files exist + # otherwise it fails + features_list = [FeatureExtraction(detector, descriptor, loadFile=store) + for ((detector, descriptor), store) in functions_and_files] + + # this takes close to an hour + # perhaps the precompiled version uses less clusters and + # less max_iterations? I don't know. + results = [] + for index, feats in enumerate(features_list): + accs = [] + for k in range(5): + # Split into a testing set and a test set. + data_train, label_train, data_test, label_test = createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = myFastBagOfVisualWords(data_train, data_test, clusters=1000, maxiter=300) + # Perform Kmeans to find centroids for clusters. + #BOF_tr, BOF_ts = BagOfWords(data_train, data_test) + print(BOF_tr.shape, BOF_ts.shape) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + detector, descriptor = detector_descriptor_names[index] + results.append(f"{detector}, {descriptor} :\t{100.0*np.mean(accs):.3f}\n") + with open("mean_acc_mybovw_1000_results.txt", 'w') as file: + for result in results: + file.write(result) + + # This is perhaps a little bit faster. It takes + # around 30 minutes instead of 60. The number of iterations + # do not seem to make it much better. Increasing + # the tolerance makes it a bit faster, but the + # accuracy is also slightly decreased. + results = [] + for index, feats in enumerate(features_list): + accs = [] + for k in range(5): + # Split into a testing set and a test set. + data_train, label_train, data_test, label_test = createTrainTest(feats, k) + + # Perform Kmeans to find centroids for clusters. + BOF_tr, BOF_ts = myFastBagOfVisualWords(data_train, data_test, clusters=500, maxiter=100) + # Perform Kmeans to find centroids for clusters. + #BOF_tr, BOF_ts = BagOfWords(data_train, data_test) + #print(BOF_tr.shape, BOF_ts.shape) + + # Train an svm on the training set and make predictions on the test set + acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test) + accs.append(acc) + detector, descriptor = detector_descriptor_names[index] + results.append(f"{detector}, {descriptor} :\t{100.0*np.mean(accs):.3f}\n") + with open("mean_acc_mybovw_500_results.txt", 'w') as file: + for result in results: + file.write(result) \ No newline at end of file diff --git a/lab1/part3/image_classification_original_utils.py b/lab1/part3/image_classification_original_utils.py new file mode 100644 index 0000000..8dc3049 --- /dev/null +++ b/lab1/part3/image_classification_original_utils.py @@ -0,0 +1,89 @@ +import sys +sys.path.append('../part12') +import numpy as np +from scipy.spatial.distance import cdist +from sklearn.cluster import KMeans + +from cv23_lab1_part3_utils import featuresSURF +from cv23_lab1_part3_utils import featuresHOG +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from box_detection_utils import BoxLaplacian + + +# define descriptors and detectors +# also define their names in order to +# accomodate easier file creation +descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)] +detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05), + lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6), + lambda i: BlobDetection(i, 2, 0.005), + lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6), + lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)] +descriptor_names = ["featuresSURF", "featuresHOG"] +detector_names = ["CornerDetection", "HarrisLaplacian", "BlobDetection", "HessianLaplacian", "BoxLaplacian"] +detector_descriptor = [(detector, descriptor) + for detector in detectors + for descriptor in descriptors] +detector_descriptor_names = [(detector, descriptor) + for detector in detector_names + for descriptor in descriptor_names] + +# THIS FUNCTION IS DEFINED FOR EDUCATIONAL PURPOSES +# IT IS NOT USED BECAUSE IT IS EXTREMELY SLOW +def kmeans(X, k, max_iters=100): + # X is the input data + # k is the number of clusters to form + # max_iters is the maximum number of iterations allowed + # returns the centroids and their labels + + n_samples, _ = X.shape + + # Initialize the cluster centroids randomly + centroids = X[np.random.choice(n_samples, size=k, replace=False)] + + for _ in range(max_iters): + # Assign each data point to the nearest cluster centroid + distances = np.linalg.norm(X[:, np.newaxis, :] - centroids, axis=-1) # shape (n_samples, k) + labels = np.argmin(distances, axis=-1) # shape (n_samples,) + + # Update the cluster centroids as the mean of the data points in each cluster + for i in range(k): + mask = (labels == i) + if np.sum(mask) > 0: + centroids[i] = np.mean(X[mask], axis=0) + + return centroids, labels + + +def myFastBagOfVisualWords(train, test, clusters=500, maxiter=100): + train_feature = np.concatenate(train, axis=0) + #test_feature = np.concatenate(test, axis=0) + + # Set the number of clusters (visual words) + # you can choose random number of clusters + # clusters = random.randint(500, 2000) + # clusters = 1000 # You can change this value + + # Perform k-means clustering + kmeans = KMeans(n_clusters=clusters, random_state=0, max_iter=maxiter, tol=0.001).fit(train_feature) + + # Function to compute the BoVW representation for a set of images + def compute_bovw(feature_set): + bovw_set = [] + for features in feature_set: + distances = cdist(features, kmeans.cluster_centers_, metric='euclidean') + labels = np.argmin(distances, axis=-1) + counts = np.bincount(labels, minlength=clusters) + l2norm = np.sqrt(np.sum(counts * counts)) + bovw = counts / l2norm + bovw_set.append(bovw) + return np.array(bovw_set) + + # Compute the BoVW representation for the training and testing sets + train_bovw = compute_bovw(train) + test_bovw = compute_bovw(test) + + return train_bovw, test_bovw diff --git a/lab1/part3/image_matching.py b/lab1/part3/image_matching.py new file mode 100644 index 0000000..7a83bb2 --- /dev/null +++ b/lab1/part3/image_matching.py @@ -0,0 +1,65 @@ +import sys +sys.path.append('../part12') +import numpy as np + +from cv23_lab1_part3_utils import featuresSURF +from cv23_lab1_part3_utils import featuresHOG +from cv23_lab1_part3_utils import matching_evaluation +from corner_detection_utils import CornerDetection +from corner_detection_utils import HarrisLaplacian +from blob_detection_utils import BlobDetection +from blob_detection_utils import HessianLaplacian +from box_detection_utils import BoxLaplacian + + +# define descriptors and detectors +# also define their names in order to +# accomodate easier file creation +descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)] +detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05), + lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6), + lambda i: BlobDetection(i, 2, 0.005), + lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6), + lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)] +descriptor_names = ["featuresSURF", "featuresHOG"] +detector_names = ["CornerDetection", "HarrisLaplacian", "BlobDetection", "HessianLaplacian", "BoxLaplacian"] +detector_descriptor = [(detector, descriptor) + for detector in detectors + for descriptor in descriptors] + +if __name__ == '__main__': + # this takes around 1-2 minutes + avg_scale_errors_list = np.zeros((len(descriptors), len(detectors), 3)) + avg_theta_errors_list = np.zeros((len(descriptors), len(detectors), 3)) + for index, descriptor in enumerate(descriptors): + for jndex, detector in enumerate(detectors): + avg_scale_errors_list[index, jndex], avg_theta_errors_list[index, jndex] = matching_evaluation(detector, descriptor) + + np.set_printoptions(precision=3) + minim = np.mean(avg_scale_errors_list[0,0]) + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if minim > np.mean(avg_scale_errors_list[index, jndex]): + minim = np.mean(avg_scale_errors_list[index, jndex]) + bestpair = (descriptor, detector) + with open("../report/avg_scale_errors.txt", 'w') as file: + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if (descriptor, detector) == bestpair: + file.write(f"{descriptor}, {detector} :\t{avg_scale_errors_list[index, jndex]}\t BEST\n") + else: + file.write(f"{descriptor}, {detector} :\t{avg_scale_errors_list[index, jndex]}\t\n") + + minim = np.mean(avg_theta_errors_list[0,0]) + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if minim > np.mean(avg_scale_errors_list[index, jndex]): + minim = np.mean(avg_scale_errors_list[index, jndex]) + bestpair = (descriptor, detector) + with open("../report/avg_theta_errors.txt", 'w') as file: + for index, descriptor in enumerate(descriptor_names): + for jndex, detector in enumerate(detector_names): + if (descriptor, detector) == bestpair: + file.write(f"{descriptor}, {detector} :\t{avg_theta_errors_list[index, jndex]}\t BEST\n") + else: + file.write(f"{descriptor}, {detector} :\t{avg_theta_errors_list[index, jndex]}\n") \ No newline at end of file diff --git a/lab1/part3/live_developement.ipynb b/lab1/part3/live_developement.ipynb new file mode 100644 index 0000000..6f1eff8 --- /dev/null +++ b/lab1/part3/live_developement.ipynb @@ -0,0 +1,400 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "sys.path.append('../part12')\n", + "import numpy as np\n", + "\n", + "from cv23_lab1_part3_utils import featuresSURF\n", + "from cv23_lab1_part3_utils import featuresHOG\n", + "from cv23_lab1_part3_utils import matching_evaluation\n", + "from cv23_lab1_part3_utils import FeatureExtraction\n", + "from cv23_lab1_part3_utils import createTrainTest\n", + "from cv23_lab1_part3_utils import BagOfWords\n", + "from cv23_lab1_part3_utils import svm\n", + "from corner_detection_utils import CornerDetection\n", + "from corner_detection_utils import HarrisLaplacian\n", + "from blob_detection_utils import BlobDetection\n", + "from blob_detection_utils import HessianLaplacian\n", + "from box_detection_utils import BoxLaplacian" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Image Matching" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)]\n", + "detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.1),\n", + " lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.1, 1.2, 6),\n", + " lambda i: BlobDetection(i, 3, 0.15),\n", + " lambda i: HessianLaplacian(i, 3, 0.15, 1.2, 6),\n", + " lambda i: BoxLaplacian(i, 3, 0.05, 1.2, 6)]\n", + "descriptor_names = [\"featuresSURF\", \"featuresHOG\"]\n", + "detector_names = [\"CornerDetection\", \"HarrisLaplacian\", \"BlobDetection\", \"HessianLaplacian\", \"BoxLaplacian\"]\n", + "detector_descriptor = [(detector, descriptor)\n", + " for detector in detectors\n", + " for descriptor in descriptors]\n", + "detector_descriptor_names = [(detector, descriptor)\n", + " for detector in detector_names\n", + " for descriptor in descriptor_names]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# this takes around 1-2 minutes\n", + "avg_scale_errors_list = np.zeros((len(descriptors), len(detectors), 3))\n", + "avg_theta_errors_list = np.zeros((len(descriptors), len(detectors), 3))\n", + "for index, descriptor in enumerate(descriptors):\n", + " for jndex, detector in enumerate(detectors):\n", + " avg_scale_errors_list[index, jndex], avg_theta_errors_list[index, jndex] = matching_evaluation(detector, descriptor)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "np.set_printoptions(precision=3)\n", + "minim = np.mean(avg_scale_errors_list[0,0])\n", + "for index, descriptor in enumerate(descriptor_names):\n", + " for jndex, detector in enumerate(detector_names):\n", + " if minim > np.mean(avg_scale_errors_list[index, jndex]):\n", + " minim = np.mean(avg_scale_errors_list[index, jndex])\n", + " bestpair = (descriptor, detector)\n", + "with open(\"../report/avg_scale_errors_trial.txt\", 'w') as file:\n", + " for index, descriptor in enumerate(descriptor_names):\n", + " for jndex, detector in enumerate(detector_names):\n", + " if (descriptor, detector) == bestpair:\n", + " file.write(f\"{descriptor}, {detector} :\\t{avg_scale_errors_list[index, jndex]}\\t BEST\\n\")\n", + " else:\n", + " file.write(f\"{descriptor}, {detector} :\\t{avg_scale_errors_list[index, jndex]}\\t\\n\")\n", + "\n", + "minim = np.mean(avg_theta_errors_list[0,0])\n", + "for index, descriptor in enumerate(descriptor_names):\n", + " for jndex, detector in enumerate(detector_names):\n", + " if minim > np.mean(avg_scale_errors_list[index, jndex]):\n", + " minim = np.mean(avg_scale_errors_list[index, jndex])\n", + " bestpair = (descriptor, detector)\n", + "with open(\"../report/avg_theta_errors_trial.txt\", 'w') as file:\n", + " for index, descriptor in enumerate(descriptor_names):\n", + " for jndex, detector in enumerate(detector_names):\n", + " if (descriptor, detector) == bestpair:\n", + " file.write(f\"{descriptor}, {detector} :\\t{avg_theta_errors_list[index, jndex]}\\t BEST\\n\")\n", + " else:\n", + " file.write(f\"{descriptor}, {detector} :\\t{avg_theta_errors_list[index, jndex]}\\n\")\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Feature Extraction" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "files = [\"./features-trial/\"+detector+'_'+descriptor+\".txt\"\n", + " for detector in detector_names\n", + " for descriptor in descriptor_names]\n", + "for name in files:\n", + " os.mknod(name)\n", + "functions_and_files = list(zip(detector_descriptor, files))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Time for feature extraction: 23.934\n", + "Time for feature extraction: 24.199\n", + "Time for feature extraction: 289.699\n", + "Time for feature extraction: 282.912\n", + "Time for feature extraction: 44.329\n", + "Time for feature extraction: 28.356\n", + "Time for feature extraction: 551.242\n", + "Time for feature extraction: 384.210\n", + "Time for feature extraction: 563.812\n", + "Time for feature extraction: 438.987\n" + ] + } + ], + "source": [ + "# this takes around 20 minutes\n", + "# DO NOT EXECUTE THIS CELL IF THE \"FEATURES\" DIRECTORY EXISTS\n", + "# IF IT EXISTS, EXECUTE THE NEXT CELL.\n", + "features_list = [FeatureExtraction(detector, descriptor, saveFile=store)\n", + " for ((detector, descriptor), store) in functions_and_files]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# this is instant provided that the files exist\n", + "features_list = [FeatureExtraction(detector, descriptor, loadFile=store) \n", + " for ((detector, descriptor), store) in functions_and_files]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "57.931\n", + "64.828\n", + "59.586\n", + "65.241\n", + "52.552\n", + "64.276\n", + "57.103\n", + "64.000\n", + "51.034\n", + "63.862\n" + ] + } + ], + "source": [ + "results = []\n", + "for index, feats in enumerate(features_list):\n", + " accs = []\n", + " for k in range(5):\n", + " # Split into a training set and a test set.\n", + " data_train, label_train, data_test, label_test = createTrainTest(feats, k)\n", + "\n", + " # Perform Kmeans to find centroids for clusters.\n", + " BOF_tr, BOF_ts = BagOfWords(data_train, data_test)\n", + "\n", + " # Train an svm on the training set and make predictions on the test set\n", + " acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test)\n", + " accs.append(acc)\n", + " print(f\"{100.0*np.mean(accs):.3f}\")\n", + " detector, descriptor = detector_descriptor_names[index]\n", + " results.append(f\"{detector}, {descriptor} :\\t{100.0*np.mean(accs):.3f}\\n\")\n", + "with open(\"mean_acc_bovw_trial_results_test.txt\", 'w') as file:\n", + " for result in results:\n", + " file.write(result)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from scipy.spatial.distance import cdist\n", + "from sklearn.cluster import KMeans\n", + "\n", + "def myFastBagOfVisualWords(train, test, clusters=500, maxiter=100):\n", + " train_feature = np.concatenate(train, axis=0)\n", + " #test_feature = np.concatenate(test, axis=0)\n", + "\n", + " # Set the number of clusters (visual words)\n", + " # you can choose random number of clusters\n", + " # clusters = random.randint(500, 2000)\n", + " # clusters = 1000 # You can change this value\n", + "\n", + " # Perform k-means clustering\n", + " kmeans = KMeans(n_clusters=clusters, random_state=0, max_iter=maxiter, tol=0.001).fit(train_feature)\n", + "\n", + " # Function to compute the BoVW representation for a set of images\n", + " def compute_bovw(feature_set):\n", + " bovw_set = []\n", + " for features in feature_set:\n", + " distances = cdist(features, kmeans.cluster_centers_, metric='euclidean')\n", + " labels = np.argmin(distances, axis=-1)\n", + " counts = np.bincount(labels, minlength=clusters)\n", + " l2norm = np.sqrt(np.sum(counts * counts))\n", + " bovw = counts / l2norm\n", + " bovw_set.append(bovw)\n", + " return np.array(bovw_set)\n", + "\n", + " # Compute the BoVW representation for the training and testing sets\n", + " train_bovw = compute_bovw(train)\n", + " test_bovw = compute_bovw(test)\n", + "\n", + " return train_bovw, test_bovw\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# this takes close to an hour\n", + "# perhaps the precompiled version uses less clusters and \n", + "# less max_iterations? I don't know.\n", + "results = []\n", + "for index, feats in enumerate(features_list):\n", + " accs = []\n", + " for k in range(5):\n", + " # Split into a testing set and a test set.\n", + " data_train, label_train, data_test, label_test = createTrainTest(feats, k)\n", + "\n", + " # Perform Kmeans to find centroids for clusters.\n", + " BOF_tr, BOF_ts = myFastBagOfVisualWords(data_train, data_test, clusters=1000, maxiter=300)\n", + " # Perform Kmeans to find centroids for clusters.\n", + " #BOF_tr, BOF_ts = BagOfWords(data_train, data_test)\n", + " print(BOF_tr.shape, BOF_ts.shape)\n", + "\n", + " # Train an svm on the training set and make predictions on the test set\n", + " acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test)\n", + " accs.append(acc)\n", + " detector, descriptor = detector_descriptor_names[index]\n", + " results.append(f\"{detector}, {descriptor} :\\t{100.0*np.mean(accs):.3f}\\n\")\n", + "with open(\"mean_acc_mybovw_1000_trial_results.txt\", 'w') as file:\n", + " for result in results:\n", + " file.write(result)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n", + "(337, 500) (145, 500)\n" + ] + } + ], + "source": [ + "# This is perhaps a little bit faster. It takes\n", + "# around 30 minutes instead of 60. The number of iterations\n", + "# do not seem to make it much better. Increasing\n", + "# the tolerance makes it a bit faster, but the\n", + "# accuracy is also slightly decreased.\n", + "results = []\n", + "for index, feats in enumerate(features_list):\n", + " accs = []\n", + " for k in range(5):\n", + " # Split into a testing set and a test set.\n", + " data_train, label_train, data_test, label_test = createTrainTest(feats, k)\n", + "\n", + " # Perform Kmeans to find centroids for clusters.\n", + " BOF_tr, BOF_ts = myFastBagOfVisualWords(data_train, data_test, clusters=500, maxiter=100)\n", + "\n", + " # Train an svm on the training set and make predictions on the test set\n", + " acc, preds, probas = svm(BOF_tr, label_train, BOF_ts, label_test)\n", + " accs.append(acc)\n", + " detector, descriptor = detector_descriptor_names[index]\n", + " results.append(f\"{detector}, {descriptor} :\\t{100.0*np.mean(accs):.3f}\\n\")\n", + " \n", + "with open(\"mean_acc_mybovw_500_trial_results.txt\", 'w') as file:\n", + " for result in results:\n", + " file.write(result)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cv_lab1_env", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.16" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lab1/part3/mean_acc_bovw/mean_acc_BlobDetection_featuresHOG.txt b/lab1/part3/mean_acc_bovw/mean_acc_BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..cf6d7b2 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_BlobDetection_featuresHOG.txt @@ -0,0 +1 @@ +BlobDetection featuresHOG: 66.345 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_BlobDetection_featuresSURF.txt b/lab1/part3/mean_acc_bovw/mean_acc_BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..fcdb7a2 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_BlobDetection_featuresSURF.txt @@ -0,0 +1 @@ +BlobDetection featuresSURF: 55.862 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_BoxLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_bovw/mean_acc_BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..a241a0a --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_BoxLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +BoxLaplacian featuresHOG: 61.517 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_BoxLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_bovw/mean_acc_BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..8fa81be --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_BoxLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +BoxLaplacian featuresSURF: 53.379 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_CornerDetection_featuresHOG.txt b/lab1/part3/mean_acc_bovw/mean_acc_CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..450b862 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_CornerDetection_featuresHOG.txt @@ -0,0 +1 @@ +CornerDetection featuresHOG: 63.724 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_CornerDetection_featuresSURF.txt b/lab1/part3/mean_acc_bovw/mean_acc_CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..b791743 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_CornerDetection_featuresSURF.txt @@ -0,0 +1 @@ +CornerDetection featuresSURF: 51.862 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..e828dee --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresHOG: 66.483 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..b87d767 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_HarrisLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresSURF: 59.310 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_HessianLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_bovw/mean_acc_HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..5a5d037 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_HessianLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HessianLaplacian featuresHOG: 63.586 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_HessianLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_bovw/mean_acc_HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..66c5a7b --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_HessianLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HessianLaplacian featuresSURF: 57.103 \ No newline at end of file diff --git a/lab1/part3/mean_acc_bovw/mean_acc_results.txt b/lab1/part3/mean_acc_bovw/mean_acc_results.txt new file mode 100644 index 0000000..dac2a55 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_results.txt @@ -0,0 +1,11 @@ +BlobDetection featuresHOG: 66.345 +BlobDetection featuresSURF: 55.862 +BoxLaplacian featuresHOG: 61.517 +BoxLaplacian featuresSURF: 53.379 +CornerDetection featuresHOG: 63.724 +CornerDetection featuresSURF: 51.862 +HarrisLaplacian featuresHOG: 66.483 +HarrisLaplacian featuresSURF: 59.310 +HessianLaplacian featuresHOG: 63.586 +HessianLaplacian featuresSURF: 57.103 + diff --git a/lab1/part3/mean_acc_bovw/mean_acc_results_sorted.txt b/lab1/part3/mean_acc_bovw/mean_acc_results_sorted.txt new file mode 100644 index 0000000..d7b6c63 --- /dev/null +++ b/lab1/part3/mean_acc_bovw/mean_acc_results_sorted.txt @@ -0,0 +1,10 @@ +HarrisLaplacian featuresHOG: 66.483 +BlobDetection featuresHOG: 66.345 +CornerDetection featuresHOG: 63.724 +HessianLaplacian featuresHOG: 63.586 +BoxLaplacian featuresHOG: 61.517 +HarrisLaplacian featuresSURF: 59.310 +HessianLaplacian featuresSURF: 57.103 +BlobDetection featuresSURF: 55.862 +BoxLaplacian featuresSURF: 53.379 +CornerDetection featuresSURF: 51.862 diff --git a/lab1/part3/mean_acc_bovw_trial_results_test.txt b/lab1/part3/mean_acc_bovw_trial_results_test.txt new file mode 100644 index 0000000..d4ffc61 --- /dev/null +++ b/lab1/part3/mean_acc_bovw_trial_results_test.txt @@ -0,0 +1,10 @@ +CornerDetection, featuresSURF : 57.931 +CornerDetection, featuresHOG : 64.828 +HarrisLaplacian, featuresSURF : 59.586 +HarrisLaplacian, featuresHOG : 65.241 +BlobDetection, featuresSURF : 52.552 +BlobDetection, featuresHOG : 64.276 +HessianLaplacian, featuresSURF : 57.103 +HessianLaplacian, featuresHOG : 64.000 +BoxLaplacian, featuresSURF : 51.034 +BoxLaplacian, featuresHOG : 63.862 diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresHOG.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..124c32b --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresHOG.txt @@ -0,0 +1 @@ +BlobDetection featuresHOG: 64.552 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresSURF.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..f8e5dcd --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BlobDetection_featuresSURF.txt @@ -0,0 +1 @@ +BlobDetection featuresSURF: 54.345 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..5daf3c2 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +BoxLaplacian featuresHOG: 62.207 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..9670d9d --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_BoxLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +BoxLaplacian featuresSURF: 52.552 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresHOG.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..fa3caed --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresHOG.txt @@ -0,0 +1 @@ +CornerDetection featuresHOG: 61.379 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresSURF.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..f0977cd --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_CornerDetection_featuresSURF.txt @@ -0,0 +1 @@ +CornerDetection featuresSURF: 56.966 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..d6d6489 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresHOG: 65.103 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..ff9b7d4 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HarrisLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresSURF: 57.793 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..359bbd8 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HessianLaplacian featuresHOG: 65.517 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..213158e --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_HessianLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HessianLaplacian featuresSURF: 59.586 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_results.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_results.txt new file mode 100644 index 0000000..12bed9a --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_results.txt @@ -0,0 +1,11 @@ +BlobDetection featuresHOG: 64.552 +BlobDetection featuresSURF: 54.345 +BoxLaplacian featuresHOG: 62.207 +BoxLaplacian featuresSURF: 52.552 +CornerDetection featuresHOG: 61.379 +CornerDetection featuresSURF: 56.966 +HarrisLaplacian featuresHOG: 65.103 +HarrisLaplacian featuresSURF: 57.793 +HessianLaplacian featuresHOG: 65.517 +HessianLaplacian featuresSURF: 59.586 + diff --git a/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt new file mode 100644 index 0000000..2af56f5 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt @@ -0,0 +1,10 @@ +HessianLaplacian featuresHOG: 65.517 +HarrisLaplacian featuresHOG: 65.103 +BlobDetection featuresHOG: 64.552 +BoxLaplacian featuresHOG: 62.207 +CornerDetection featuresHOG: 61.379 +HessianLaplacian featuresSURF: 59.586 +HarrisLaplacian featuresSURF: 57.793 +CornerDetection featuresSURF: 56.966 +BlobDetection featuresSURF: 54.345 +BoxLaplacian featuresSURF: 52.552 diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresHOG.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresHOG.txt new file mode 100644 index 0000000..42d7fad --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresHOG.txt @@ -0,0 +1 @@ +BlobDetection featuresHOG: 65.931 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresSURF.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresSURF.txt new file mode 100644 index 0000000..5b356a2 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BlobDetection_featuresSURF.txt @@ -0,0 +1 @@ +BlobDetection featuresSURF: 53.655 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresHOG.txt new file mode 100644 index 0000000..b374c4a --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +BoxLaplacian featuresHOG: 65.931 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresSURF.txt new file mode 100644 index 0000000..cc74e39 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_BoxLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +BoxLaplacian featuresSURF: 54.483 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresHOG.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresHOG.txt new file mode 100644 index 0000000..5e31c8b --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresHOG.txt @@ -0,0 +1 @@ +CornerDetection featuresHOG: 64.690 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresSURF.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresSURF.txt new file mode 100644 index 0000000..21bc49e --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_CornerDetection_featuresSURF.txt @@ -0,0 +1 @@ +CornerDetection featuresSURF: 54.621 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresHOG.txt new file mode 100644 index 0000000..d3df9fe --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresHOG: 64.828 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresSURF.txt new file mode 100644 index 0000000..c9a3754 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HarrisLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HarrisLaplacian featuresSURF: 58.207 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresHOG.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresHOG.txt new file mode 100644 index 0000000..7f25651 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresHOG.txt @@ -0,0 +1 @@ +HessianLaplacian featuresHOG: 64.690 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresSURF.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresSURF.txt new file mode 100644 index 0000000..4a930b9 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_HessianLaplacian_featuresSURF.txt @@ -0,0 +1 @@ +HessianLaplacian featuresSURF: 56.552 \ No newline at end of file diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results.txt new file mode 100644 index 0000000..ea78b2e --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results.txt @@ -0,0 +1,11 @@ +BlobDetection featuresHOG: 65.931 +BlobDetection featuresSURF: 53.655 +BoxLaplacian featuresHOG: 65.931 +BoxLaplacian featuresSURF: 54.483 +CornerDetection featuresHOG: 64.690 +CornerDetection featuresSURF: 54.621 +HarrisLaplacian featuresHOG: 64.828 +HarrisLaplacian featuresSURF: 58.207 +HessianLaplacian featuresHOG: 64.690 +HessianLaplacian featuresSURF: 56.552 + diff --git a/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt new file mode 100644 index 0000000..9820e46 --- /dev/null +++ b/lab1/part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt @@ -0,0 +1,10 @@ +BlobDetection featuresHOG: 65.931 +BoxLaplacian featuresHOG: 65.931 +HarrisLaplacian featuresHOG: 64.828 +CornerDetection featuresHOG: 64.690 +HessianLaplacian featuresHOG: 64.690 +HarrisLaplacian featuresSURF: 58.207 +HessianLaplacian featuresSURF: 56.552 +CornerDetection featuresSURF: 54.621 +BoxLaplacian featuresSURF: 54.483 +BlobDetection featuresSURF: 53.655 diff --git a/lab1/part3/snrImgSet.mat b/lab1/part3/snrImgSet.mat new file mode 100644 index 0000000..417e063 Binary files /dev/null and b/lab1/part3/snrImgSet.mat differ diff --git a/lab1/proxeirocvlab1.txt b/lab1/proxeirocvlab1.txt deleted file mode 100644 index 4fc4f6e..0000000 --- a/lab1/proxeirocvlab1.txt +++ /dev/null @@ -1,62 +0,0 @@ - - #ix, iy = image.shape - #result = np.zeros((n + ix - 1, n + iy - 1)) - #padded = np.pad(image, [(n//2, n//2), (n//2, n//2)], mode='constant') - #for i in range(n//2, ix + n//2): - # for j in range(n//2, iy + n//2): - # result[i,j] = np.sum(padded[i-n//2:i+n//2+1, j-n//2:j+n//2+1] * kernel) - #return result[n//2:ix+n//2, n//2:iy+n//2] - - #logkernel = np.zeros((3 + n//2 - 1, 3 + n//2 - 1)) - #padded = np.pad(kernel, [(3//2,3//2),(3//2,3//2)], mode='constant') - #for i in range(3//2, n + 3//2): - # for j in range(3//2, n + 3//2): - # logkernel[i,j] = np.sum(padded[i - 3//2:i+3//2+1, j-3//2:j+3//2+1 ] * laplacian) - - kx = cv2.getGaussianKernel(n, sigma) - ky = cv2.getGaussianKernel(n, sigma) - kernel = np.multiply(kx, np.transpose(ky)) - # this isn't really necessary, it preserves brightness - kernel = kernel/np.sum(kernel) - - #ix, iy = image.shape - #n = logkernel.shape[0] - #result = np.zeros((n + ix - 1, n + iy - 1)) - #padded = np.pad(image, [(n//2, n//2), (n//2, n//2)], mode='constant') - #for i in range(n//2, ix + n//2): - # for j in range(n//2, iy + n//2): - # result[i,j] = np.sum(padded[i-n//2:i+n//2+1, j-n//2:j+n//2+1] * kernel) - #return result[n//2:ix+n//2, n//2:iy+n//2] -def myfilter(image, sigma, method): - if (method == "gaussian"): - n = int(np.ceil(3*sigma)*2 + 1) - # generating the kernels using meshgrid is - # said to be more accurate than multiplying - # two 1d gaussian kernels together. That is - # because the product of two gaussian functions - # is not neccessarily a gaussian function, so - # there may be a loss of symmetry between the - # x, y axis. - x, y = np.meshgrid(np.arange(-n//2+1, n//2+1), - np.arange(-n//2+1, n//2+1)) - kernel = np.exp(-(x**2+y**2)/(2*sigma**2)) - # this isn't really necessary, it preserves brightness - kernel = kernel/np.sum(kernel) - result = my2dconv(image, kernel) - return result - if (method == "log"): - n = int(np.ceil(3*sigma)*2 + 1) - x, y = np.meshgrid(np.arange(-n//2+1, n//2+1), - np.arange(-n//2+1, n//2+1)) - kernel = np.exp(-(x**2+y**2)/(2*sigma**2)) - # this isn't really necessary, it preserves brightness - kernel = kernel/np.sum(kernel) - laplacian = np.array([[0,1,0], - [1,-4,1], - [0,1,0]]) - # perform the convolution between the gaussian kernel - # and the laplacian, in order to create the log kernel - logkernel = my2dconv(kernel, laplacian) - result = my2dconv(image, logkernel) - return result - print("Error: method has to be either \"gaussian\" or \"log\"") diff --git a/lab1/report/avg_scale_errors.txt b/lab1/report/avg_scale_errors.txt new file mode 100644 index 0000000..effb0f1 --- /dev/null +++ b/lab1/report/avg_scale_errors.txt @@ -0,0 +1,10 @@ +featuresSURF, CornerDetection : [0.003 0.002 0.097] +featuresSURF, HarrisLaplacian : [0.001 0.002 0.002] +featuresSURF, BlobDetection : [0.027 0.01 0.001] +featuresSURF, HessianLaplacian : [0.002 0.001 0.001] BEST +featuresSURF, BoxLaplacian : [0.073 0.086 0.003] +featuresHOG, CornerDetection : [0.186 0.351 0.285] +featuresHOG, HarrisLaplacian : [0.202 0.137 0.717] +featuresHOG, BlobDetection : [0.186 0.1 0.154] +featuresHOG, HessianLaplacian : [0.162 0.114 0.253] +featuresHOG, BoxLaplacian : [0.856 0.283 0.185] diff --git a/lab1/report/avg_scale_errors_trial.txt b/lab1/report/avg_scale_errors_trial.txt new file mode 100644 index 0000000..bc69757 --- /dev/null +++ b/lab1/report/avg_scale_errors_trial.txt @@ -0,0 +1,10 @@ +featuresSURF, CornerDetection : [0.019 0.003 0.218] +featuresSURF, HarrisLaplacian : [0.002 0.002 0.002] BEST +featuresSURF, BlobDetection : [0.018 0.242 0.017] +featuresSURF, HessianLaplacian : [0.002 0.004 0.002] +featuresSURF, BoxLaplacian : [0.061 0.026 0.01 ] +featuresHOG, CornerDetection : [0.149 0.43 0.228] +featuresHOG, HarrisLaplacian : [0.446 0.804 0.204] +featuresHOG, BlobDetection : [0.222 0.316 0.229] +featuresHOG, HessianLaplacian : [0.551 0.406 0.714] +featuresHOG, BoxLaplacian : [0.279 0.224 0.401] diff --git a/lab1/report/avg_theta_errors.txt b/lab1/report/avg_theta_errors.txt new file mode 100644 index 0000000..e37e253 --- /dev/null +++ b/lab1/report/avg_theta_errors.txt @@ -0,0 +1,10 @@ +featuresSURF, CornerDetection : [ 1.968 0.318 12.909] +featuresSURF, HarrisLaplacian : [0.077 0.169 0.099] +featuresSURF, BlobDetection : [7.759 0.229 0.054] +featuresSURF, HessianLaplacian : [0.064 0.11 0.05 ] BEST +featuresSURF, BoxLaplacian : [ 7.707 11.362 0.463] +featuresHOG, CornerDetection : [22.619 19.199 23.699] +featuresHOG, HarrisLaplacian : [24.426 25.926 25.471] +featuresHOG, BlobDetection : [ 7.231 13.674 27.219] +featuresHOG, HessianLaplacian : [25.439 18.598 13.546] +featuresHOG, BoxLaplacian : [16.661 23.906 14.184] diff --git a/lab1/report/avg_theta_errors_trial.txt b/lab1/report/avg_theta_errors_trial.txt new file mode 100644 index 0000000..85ff6e3 --- /dev/null +++ b/lab1/report/avg_theta_errors_trial.txt @@ -0,0 +1,10 @@ +featuresSURF, CornerDetection : [1.155 0.623 9.011] +featuresSURF, HarrisLaplacian : [0.07 0.203 0.146] BEST +featuresSURF, BlobDetection : [1.39 1.457 6.258] +featuresSURF, HessianLaplacian : [0.072 0.152 0.193] +featuresSURF, BoxLaplacian : [8.241 5.358 1.018] +featuresHOG, CornerDetection : [28.653 21.152 25.891] +featuresHOG, HarrisLaplacian : [23.278 16.421 24.032] +featuresHOG, BlobDetection : [28.587 43.324 18.595] +featuresHOG, HessianLaplacian : [16.9 24.7 25.623] +featuresHOG, BoxLaplacian : [22.649 35.67 26.149] diff --git a/lab1/report/lab1_part123_report.aux b/lab1/report/lab1_part123_report.aux new file mode 100644 index 0000000..555bcd6 --- /dev/null +++ b/lab1/report/lab1_part123_report.aux @@ -0,0 +1,106 @@ +\relax +\providecommand\babel@aux[2]{} +\@nameuse{bbl@beforestart} +\catcode `;\active +\babel@aux{greek}{} +\@writefile{toc}{\contentsline {section}{\numberline {1}Μέρος 1ο}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Δημιουργία Εικόνων Εισόδου}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Υλοποίηση Αλγορίθμων Ανίχνευσης Ακμών}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.1}Γραμμική Μέθοδος}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.2}Μη Γραμμική Μέθοδος}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Αξιολόγηση των Αποτελεσμάτων Ανίσχνευσης Ακμών}{4}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.4}Αποτελέσματα Εφαρμογής της Συνάρτησης}{4}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Η δεδομένη εικόνα εισόδου\relax }}{5}{}\protected@file@percent } +\providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}} +\newlabel{fig:edge-test}{{1}{5}} +\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Θόρυβος \foreignlanguage {english}{PSNR} 10\foreignlanguage {english}{dB}\relax }}{5}{}\protected@file@percent } +\newlabel{fig:noise 10db}{{2}{5}} +\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Θόρυβος \foreignlanguage {english}{PSNR} 20\foreignlanguage {english}{dB}\relax }}{6}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.5}Εφαρμογή των Αλγορίθμων Ανίχνευσης Ακμών σε Πραγματικές Εικόνες}{7}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Η πραγματική φωτογραφιά του \foreignlanguage {english}{Kyoto}\relax }}{7}{}\protected@file@percent } +\newlabel{fig:kyoto}{{4}{7}} +\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Ανίχνευση ακμών στην πραγματική φωτογραφιά του \foreignlanguage {english}{Kyoto}\relax }}{7}{}\protected@file@percent } +\newlabel{fig:kyoto-edges}{{5}{7}} +\@writefile{toc}{\contentsline {section}{\numberline {2}Μέρος 2ο}{8}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Ανίχνευση Γωνιών}{8}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Απεικόνιση των ιδιοτιμών της εικόνας ως γκρίζες εικόνες\relax }}{8}{}\protected@file@percent } +\newlabel{fig:kyoto-eigenvalues}{{6}{8}} +\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Ανίχνευση γωνιών στην εικόνα \foreignlanguage {english}{Kyoto}\relax }}{9}{}\protected@file@percent } +\newlabel{fig:kyoto-corners}{{7}{9}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Πολυκλιμακωτή Ανίχνευση Γωνιών}{10}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Πολυκλιμακωτή ανίχνευση γωνιών στην εικόνα \foreignlanguage {english}{Kyoto}\relax }}{10}{}\protected@file@percent } +\newlabel{fig:kyoto-corners-multiscale}{{8}{10}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Ανίχνευση \foreignlanguage {english}{Blobs}}{11}{}\protected@file@percent } +\newlabel{fig:up}{{9{\greekscript \textalpha \textnumeralsigngreek }}{11}} +\newlabel{sub@fig:up}{{{\greekscript \textalpha \textnumeralsigngreek }}{11}} +\newlabel{fig:up}{{9{\greekscript \textbeta \textnumeralsigngreek }}{11}} +\newlabel{sub@fig:up}{{{\greekscript \textbeta \textnumeralsigngreek }}{11}} +\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Οι αρχικές εικόνες για την ανίχνευση \foreignlanguage {english}{blobs}\relax }}{11}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Aνίχνευση \foreignlanguage {english}{blobs} στην εικόνα \foreignlanguage {english}{Up}\relax }}{12}{}\protected@file@percent } +\newlabel{fig:up-blobs}{{10}{12}} +\newlabel{fig:cells-bad}{{11{\greekscript \textalpha \textnumeralsigngreek }}{12}} +\newlabel{sub@fig:cells-bad}{{{\greekscript \textalpha \textnumeralsigngreek }}{12}} +\newlabel{fig:cells-good}{{11{\greekscript \textbeta \textnumeralsigngreek }}{12}} +\newlabel{sub@fig:cells-good}{{{\greekscript \textbeta \textnumeralsigngreek }}{12}} +\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Η εικόνα των κυττάρων γκρίζα\relax }}{13}{}\protected@file@percent } +\newlabel{fig:cells-gray}{{12}{13}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Πολυκλιμακωτή Ανίχνευση \foreignlanguage {english}{Blobs}}{13}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Πολυκλιμακωτή ανίχνευση \foreignlanguage {english}{blobs} στην εικόνα \foreignlanguage {english}{Up}\relax }}{14}{}\protected@file@percent } +\newlabel{fig:up-multiscale}{{13}{14}} +\newlabel{fig:cells-multiscale-bad}{{14{\greekscript \textalpha \textnumeralsigngreek }}{15}} +\newlabel{sub@fig:cells-multiscale-bad}{{{\greekscript \textalpha \textnumeralsigngreek }}{15}} +\newlabel{fig:cells-multiscale-good}{{14{\greekscript \textbeta \textnumeralsigngreek }}{15}} +\newlabel{sub@fig:cells-multiscale-good}{{{\greekscript \textbeta \textnumeralsigngreek }}{15}} +\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Πολυκλιμακωτή ανίχνευση \foreignlanguage {english}{blobs} σε κύτταρα\relax }}{15}{}\protected@file@percent } +\newlabel{fig:cells-multiscale-pair}{{14}{15}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Επιτάχυνση Ανίχνευσης \foreignlanguage {english}{Blobs}}{16}{}\protected@file@percent } +\newlabel{fig:up-ii}{{15{\greekscript \textalpha \textnumeralsigngreek }}{17}} +\newlabel{sub@fig:up-ii}{{{\greekscript \textalpha \textnumeralsigngreek }}{17}} +\newlabel{fig:cells-ii}{{15{\greekscript \textbeta \textnumeralsigngreek }}{17}} +\newlabel{sub@fig:cells-ii}{{{\greekscript \textbeta \textnumeralsigngreek }}{17}} +\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Προσέγγιση ανίχνευσης \foreignlanguage {english}{blobs} με ολοκληρωτικές εικόνες\relax }}{17}{}\protected@file@percent } +\newlabel{fig:ii}{{15}{17}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Επιτάχυνση Πολυκλιμακωτής Ανίχνευση \foreignlanguage {english}{Blobs}}{18}{}\protected@file@percent } +\newlabel{fig:cells-multiscale-ii}{{16{\greekscript \textalpha \textnumeralsigngreek }}{18}} +\newlabel{sub@fig:cells-multiscale-ii}{{{\greekscript \textalpha \textnumeralsigngreek }}{18}} +\newlabel{fig:cells-multiscale-ii}{{16{\greekscript \textbeta \textnumeralsigngreek }}{18}} +\newlabel{sub@fig:cells-multiscale-ii}{{{\greekscript \textbeta \textnumeralsigngreek }}{18}} +\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Προσέγγιση πολυκλιμακωτής ανίχνευσης \foreignlanguage {english}{blobs} με ολοκληρωτικές εικόνες\relax }}{18}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {3}Μέρος 3ο}{19}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Ταίριασμα Εικόνων υπό Περιστροφή και Αλλαγή Κλίμακας}{19}{}\protected@file@percent } +\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Αντιστοίχιση μονοκλιμακωτών και πολυκλιμακωτών μεθόδων.\relax }}{19}{}\protected@file@percent } +\newlabel{tab:mytable}{{1}{19}} +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Σφάλματα Κλίμακας\relax }}{19}{}\protected@file@percent } +\babel@aux{english}{} +\babel@aux{greek}{} +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{lof}{\contentsline {figure}{\numberline {18}{\ignorespaces Σφάλματα Γωνίας\relax }}{20}{}\protected@file@percent } +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Κατηγοριοποίηση Εικόνων}{20}{}\protected@file@percent } +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{lof}{\contentsline {figure}{\numberline {19}{\ignorespaces Αποτελέσματα Ταξινόμησης (Προμεταγλωττισμένες Συναρτήσεις, 500 ομάδες)\relax }}{21}{}\protected@file@percent } +\babel@aux{english}{} +\babel@aux{greek}{} +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{lof}{\contentsline {figure}{\numberline {20}{\ignorespaces Αποτελέσματα Ταξινόμησης (Πρωτότυπες Συναρτήσεις, 1000 ομάδες)\relax }}{21}{}\protected@file@percent } +\babel@aux{english}{} +\babel@aux{greek}{} +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{lof}{\contentsline {figure}{\numberline {21}{\ignorespaces Αποτελέσματα Ταξινόμησης (Πρωτότυπες Συναρτήσεις, 500 ομάδες)\relax }}{22}{}\protected@file@percent } +\babel@aux{english}{} +\babel@aux{greek}{} +\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Αντιστοίχιση μονοκλιμακωτών και πολυκλιμακωτών μεθόδων για \foreignlanguage {english}{SURF} περιγραφητή.\relax }}{22}{}\protected@file@percent } +\newlabel{tab:mytable}{{2}{22}} +\@writefile{toc}{\contentsline {section}{\numberline {4}Παράρτημα}{23}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Επιτάχυνση χρήσει ολοκληρωτικών εικόνων και \foreignlanguage {english}{box filters}}{23}{}\protected@file@percent } +\newlabel{section:details}{{4.1}{23}} +\@writefile{lof}{\contentsline {figure}{\numberline {22}{\ignorespaces Σύγκριση ταχύτητας διαφόρων υλοποιήσεων υπολογισμού μερικών παραγώγων\relax }}{23}{}\protected@file@percent } +\newlabel{fig:grad-comparison}{{22}{23}} +\gdef \@abspage@last{23} diff --git a/lab1/report/lab1_part123_report.log b/lab1/report/lab1_part123_report.log new file mode 100644 index 0000000..453cb45 --- /dev/null +++ b/lab1/report/lab1_part123_report.log @@ -0,0 +1,930 @@ +This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=pdflatex 2023.3.24) 23 APR 2023 14:37 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**lab1_part123_report.tex +(./lab1_part123_report.tex +LaTeX2e <2021-11-15> patch level 1 +L3 programming layer <2022-01-21> +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2021/10/04 v1.4n Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo +File: size10.clo 2021/10/04 v1.4n Standard LaTeX file (size option) +) +\c@part=\count185 +\c@section=\count186 +\c@subsection=\count187 +\c@subsubsection=\count188 +\c@paragraph=\count189 +\c@subparagraph=\count190 +\c@figure=\count191 +\c@table=\count192 +\abovecaptionskip=\skip47 +\belowcaptionskip=\skip48 +\bibindent=\dimen138 +) +(/usr/share/texlive/texmf-dist/tex/generic/babel/babel.sty +Package: babel 2022/01/26 3.70 The Babel package +\babel@savecnt=\count193 +\U@D=\dimen139 +\l@unhyphenated=\language7 + +(/usr/share/texlive/texmf-dist/tex/generic/babel/txtbabel.def) +\bbl@readstream=\read2 +\bbl@dirlevel=\count194 + +(/usr/share/texlive/texmf-dist/tex/generic/babel-english/english.ldf +Language: english 2017/06/06 v3.3r English support from the babel system +Package babel Info: Hyphen rules for 'british' set to \l@english +(babel) (\language0). Reported on input line 82. +Package babel Info: Hyphen rules for 'UKenglish' set to \l@english +(babel) (\language0). Reported on input line 83. +Package babel Info: Hyphen rules for 'canadian' set to \l@english +(babel) (\language0). Reported on input line 102. +Package babel Info: Hyphen rules for 'australian' set to \l@english +(babel) (\language0). Reported on input line 105. +Package babel Info: Hyphen rules for 'newzealand' set to \l@english +(babel) (\language0). Reported on input line 108. +) +(/usr/share/texlive/texmf-dist/tex/generic/babel-greek/greek.ldf +Language: greek 2020/11/10 v1.10 Greek support for the babel system +\bbl@monogreek=\count195 +\bbl@polygreek=\count196 +\bbl@ancientgreek=\count197 + +(/usr/share/texlive/texmf-dist/tex/latex/greek-fontenc/lgrenc.def +File: lgrenc.def 2020/10/13 2.0 LGR Greek font encoding definitions +Now handling font encoding LGR ... +... processing UTF-8 mapping file for font encoding LGR + +(/usr/share/texlive/texmf-dist/tex/latex/greek-inputenc/lgrenc.dfu +File: lgrenc.dfu 2019/07/11 1.7 UTF-8 support for Greek + defining Unicode char U+00A8 (decimal 168) + defining Unicode char U+00AB (decimal 171) + defining Unicode char U+00AF (decimal 175) + defining Unicode char U+00B4 (decimal 180) + defining Unicode char U+00B7 (decimal 183) + defining Unicode char U+00BB (decimal 187) + defining Unicode char U+0259 (decimal 601) + defining Unicode char U+02D8 (decimal 728) + defining Unicode char U+0374 (decimal 884) + defining Unicode char U+0375 (decimal 885) + defining Unicode char U+037A (decimal 890) + defining Unicode char U+037E (decimal 894) + defining Unicode char U+0384 (decimal 900) + defining Unicode char U+0385 (decimal 901) + defining Unicode char U+0386 (decimal 902) + defining Unicode char U+0387 (decimal 903) + defining Unicode char U+0388 (decimal 904) + defining Unicode char U+0389 (decimal 905) + defining Unicode char U+038A (decimal 906) + defining Unicode char U+038C (decimal 908) + defining Unicode char U+038E (decimal 910) + defining Unicode char U+038F (decimal 911) + defining Unicode char U+0390 (decimal 912) + defining Unicode char U+0391 (decimal 913) + defining Unicode char U+0392 (decimal 914) + defining Unicode char U+0393 (decimal 915) + defining Unicode char U+0394 (decimal 916) + defining Unicode char U+0395 (decimal 917) + defining Unicode char U+0396 (decimal 918) + defining Unicode char U+0397 (decimal 919) + defining Unicode char U+0398 (decimal 920) + defining Unicode char U+0399 (decimal 921) + defining Unicode char U+039A (decimal 922) + defining Unicode char U+039B (decimal 923) + defining Unicode char U+039C (decimal 924) + defining Unicode char U+039D (decimal 925) + defining Unicode char U+039E (decimal 926) + defining Unicode char U+039F (decimal 927) + defining Unicode char U+03A0 (decimal 928) + defining Unicode char U+03A1 (decimal 929) + defining Unicode char U+03A3 (decimal 931) + defining Unicode char U+03A4 (decimal 932) + defining Unicode char U+03A5 (decimal 933) + defining Unicode char U+03A6 (decimal 934) + defining Unicode char U+03A7 (decimal 935) + defining Unicode char U+03A8 (decimal 936) + defining Unicode char U+03A9 (decimal 937) + defining Unicode char U+03AA (decimal 938) + defining Unicode char U+03AB (decimal 939) + defining Unicode char U+03AC (decimal 940) + defining Unicode char U+03AD (decimal 941) + defining Unicode char U+03AE (decimal 942) + defining Unicode char U+03AF (decimal 943) + defining Unicode char U+03B0 (decimal 944) + defining Unicode char U+03B1 (decimal 945) + defining Unicode char U+03B2 (decimal 946) + defining Unicode char U+03B3 (decimal 947) + defining Unicode char U+03B4 (decimal 948) + defining Unicode char U+03B5 (decimal 949) + defining Unicode char U+03B6 (decimal 950) + defining Unicode char U+03B7 (decimal 951) + defining Unicode char U+03B8 (decimal 952) + defining Unicode char U+03B9 (decimal 953) + defining Unicode char U+03BA (decimal 954) + defining Unicode char U+03BB (decimal 955) + defining Unicode char U+03BC (decimal 956) + defining Unicode char U+03BD (decimal 957) + defining Unicode char U+03BE (decimal 958) + defining Unicode char U+03BF (decimal 959) + defining Unicode char U+03C0 (decimal 960) + defining Unicode char U+03C1 (decimal 961) + defining Unicode char U+03C2 (decimal 962) + defining Unicode char U+03C3 (decimal 963) + defining Unicode char U+03C4 (decimal 964) + defining Unicode char U+03C5 (decimal 965) + defining Unicode char U+03C6 (decimal 966) + defining Unicode char U+03C7 (decimal 967) + defining Unicode char U+03C8 (decimal 968) + defining Unicode char U+03C9 (decimal 969) + defining Unicode char U+03CA (decimal 970) + defining Unicode char U+03CB (decimal 971) + defining Unicode char U+03CC (decimal 972) + defining Unicode char U+03CD (decimal 973) + defining Unicode char U+03CE (decimal 974) + defining Unicode char U+03D0 (decimal 976) + defining Unicode char U+03D1 (decimal 977) + defining Unicode char U+03D5 (decimal 981) + defining Unicode char U+03D6 (decimal 982) + defining Unicode char U+03D8 (decimal 984) + defining Unicode char U+03D9 (decimal 985) + defining Unicode char U+03DA (decimal 986) + defining Unicode char U+03DB (decimal 987) + defining Unicode char U+03DC (decimal 988) + defining Unicode char U+03DD (decimal 989) + defining Unicode char U+03DF (decimal 991) + defining Unicode char U+03E0 (decimal 992) + defining Unicode char U+03E1 (decimal 993) + defining Unicode char U+03F0 (decimal 1008) + defining Unicode char U+03F1 (decimal 1009) + defining Unicode char U+03F4 (decimal 1012) + defining Unicode char U+03F5 (decimal 1013) + defining Unicode char U+1F00 (decimal 7936) + defining Unicode char U+1F01 (decimal 7937) + defining Unicode char U+1F02 (decimal 7938) + defining Unicode char U+1F03 (decimal 7939) + defining Unicode char U+1F04 (decimal 7940) + defining Unicode char U+1F05 (decimal 7941) + defining Unicode char U+1F06 (decimal 7942) + defining Unicode char U+1F07 (decimal 7943) + defining Unicode char U+1F08 (decimal 7944) + defining Unicode char U+1F09 (decimal 7945) + defining Unicode char U+1F0A (decimal 7946) + defining Unicode char U+1F0B (decimal 7947) + defining Unicode char U+1F0C (decimal 7948) + defining Unicode char U+1F0D (decimal 7949) + defining Unicode char U+1F0E (decimal 7950) + defining Unicode char U+1F0F (decimal 7951) + defining Unicode char U+1F10 (decimal 7952) + defining Unicode char U+1F11 (decimal 7953) + defining Unicode char U+1F12 (decimal 7954) + defining Unicode char U+1F13 (decimal 7955) + defining Unicode char U+1F14 (decimal 7956) + defining Unicode char U+1F15 (decimal 7957) + defining Unicode char U+1F18 (decimal 7960) + defining Unicode char U+1F19 (decimal 7961) + defining Unicode char U+1F1A (decimal 7962) + defining Unicode char U+1F1B (decimal 7963) + defining Unicode char U+1F1C (decimal 7964) + defining Unicode char U+1F1D (decimal 7965) + defining Unicode char U+1F20 (decimal 7968) + defining Unicode char U+1F21 (decimal 7969) + defining Unicode char U+1F22 (decimal 7970) + defining Unicode char U+1F23 (decimal 7971) + defining Unicode char U+1F24 (decimal 7972) + defining Unicode char U+1F25 (decimal 7973) + defining Unicode char U+1F26 (decimal 7974) + defining Unicode char U+1F27 (decimal 7975) + defining Unicode char U+1F28 (decimal 7976) + defining Unicode char U+1F29 (decimal 7977) + defining Unicode char U+1F2A (decimal 7978) + defining Unicode char U+1F2B (decimal 7979) + defining Unicode char U+1F2C (decimal 7980) + defining Unicode char U+1F2D (decimal 7981) + defining Unicode char U+1F2E (decimal 7982) + defining Unicode char U+1F2F (decimal 7983) + defining Unicode char U+1F30 (decimal 7984) + defining Unicode char U+1F31 (decimal 7985) + defining Unicode char U+1F32 (decimal 7986) + defining Unicode char U+1F33 (decimal 7987) + defining Unicode char U+1F34 (decimal 7988) + defining Unicode char U+1F35 (decimal 7989) + defining Unicode char U+1F36 (decimal 7990) + defining Unicode char U+1F37 (decimal 7991) + defining Unicode char U+1F38 (decimal 7992) + defining Unicode char U+1F39 (decimal 7993) + defining Unicode char U+1F3A (decimal 7994) + defining Unicode char U+1F3B (decimal 7995) + defining Unicode char U+1F3C (decimal 7996) + defining Unicode char U+1F3D (decimal 7997) + defining Unicode char U+1F3E (decimal 7998) + defining Unicode char U+1F3F (decimal 7999) + defining Unicode char U+1F40 (decimal 8000) + defining Unicode char U+1F41 (decimal 8001) + defining Unicode char U+1F42 (decimal 8002) + defining Unicode char U+1F43 (decimal 8003) + defining Unicode char U+1F44 (decimal 8004) + defining Unicode char U+1F45 (decimal 8005) + defining Unicode char U+1F48 (decimal 8008) + defining Unicode char U+1F49 (decimal 8009) + defining Unicode char U+1F4A (decimal 8010) + defining Unicode char U+1F4B (decimal 8011) + defining Unicode char U+1F4C (decimal 8012) + defining Unicode char U+1F4D (decimal 8013) + defining Unicode char U+1F50 (decimal 8016) + defining Unicode char U+1F51 (decimal 8017) + defining Unicode char U+1F52 (decimal 8018) + defining Unicode char U+1F53 (decimal 8019) + defining Unicode char U+1F54 (decimal 8020) + defining Unicode char U+1F55 (decimal 8021) + defining Unicode char U+1F56 (decimal 8022) + defining Unicode char U+1F57 (decimal 8023) + defining Unicode char U+1F59 (decimal 8025) + defining Unicode char U+1F5B (decimal 8027) + defining Unicode char U+1F5D (decimal 8029) + defining Unicode char U+1F5F (decimal 8031) + defining Unicode char U+1F60 (decimal 8032) + defining Unicode char U+1F61 (decimal 8033) + defining Unicode char U+1F62 (decimal 8034) + defining Unicode char U+1F63 (decimal 8035) + defining Unicode char U+1F64 (decimal 8036) + defining Unicode char U+1F65 (decimal 8037) + defining Unicode char U+1F66 (decimal 8038) + defining Unicode char U+1F67 (decimal 8039) + defining Unicode char U+1F68 (decimal 8040) + defining Unicode char U+1F69 (decimal 8041) + defining Unicode char U+1F6A (decimal 8042) + defining Unicode char U+1F6B (decimal 8043) + defining Unicode char U+1F6C (decimal 8044) + defining Unicode char U+1F6D (decimal 8045) + defining Unicode char U+1F6E (decimal 8046) + defining Unicode char U+1F6F (decimal 8047) + defining Unicode char U+1F70 (decimal 8048) + defining Unicode char U+1F71 (decimal 8049) + defining Unicode char U+1F72 (decimal 8050) + defining Unicode char U+1F73 (decimal 8051) + defining Unicode char U+1F74 (decimal 8052) + defining Unicode char U+1F75 (decimal 8053) + defining Unicode char U+1F76 (decimal 8054) + defining Unicode char U+1F77 (decimal 8055) + defining Unicode char U+1F78 (decimal 8056) + defining Unicode char U+1F79 (decimal 8057) + defining Unicode char U+1F7A (decimal 8058) + defining Unicode char U+1F7B (decimal 8059) + defining Unicode char U+1F7C (decimal 8060) + defining Unicode char U+1F7D (decimal 8061) + defining Unicode char U+1F80 (decimal 8064) + defining Unicode char U+1F81 (decimal 8065) + defining Unicode char U+1F82 (decimal 8066) + defining Unicode char U+1F83 (decimal 8067) + defining Unicode char U+1F84 (decimal 8068) + defining Unicode char U+1F85 (decimal 8069) + defining Unicode char U+1F86 (decimal 8070) + defining Unicode char U+1F87 (decimal 8071) + defining Unicode char U+1F88 (decimal 8072) + defining Unicode char U+1F89 (decimal 8073) + defining Unicode char U+1F8A (decimal 8074) + defining Unicode char U+1F8B (decimal 8075) + defining Unicode char U+1F8C (decimal 8076) + defining Unicode char U+1F8D (decimal 8077) + defining Unicode char U+1F8E (decimal 8078) + defining Unicode char U+1F8F (decimal 8079) + defining Unicode char U+1F90 (decimal 8080) + defining Unicode char U+1F91 (decimal 8081) + defining Unicode char U+1F92 (decimal 8082) + defining Unicode char U+1F93 (decimal 8083) + defining Unicode char U+1F94 (decimal 8084) + defining Unicode char U+1F95 (decimal 8085) + defining Unicode char U+1F96 (decimal 8086) + defining Unicode char U+1F97 (decimal 8087) + defining Unicode char U+1F98 (decimal 8088) + defining Unicode char U+1F99 (decimal 8089) + defining Unicode char U+1F9A (decimal 8090) + defining Unicode char U+1F9B (decimal 8091) + defining Unicode char U+1F9C (decimal 8092) + defining Unicode char U+1F9D (decimal 8093) + defining Unicode char U+1F9E (decimal 8094) + defining Unicode char U+1F9F (decimal 8095) + defining Unicode char U+1FA0 (decimal 8096) + defining Unicode char U+1FA1 (decimal 8097) + defining Unicode char U+1FA2 (decimal 8098) + defining Unicode char U+1FA3 (decimal 8099) + defining Unicode char U+1FA4 (decimal 8100) + defining Unicode char U+1FA5 (decimal 8101) + defining Unicode char U+1FA6 (decimal 8102) + defining Unicode char U+1FA7 (decimal 8103) + defining Unicode char U+1FA8 (decimal 8104) + defining Unicode char U+1FA9 (decimal 8105) + defining Unicode char U+1FAA (decimal 8106) + defining Unicode char U+1FAB (decimal 8107) + defining Unicode char U+1FAC (decimal 8108) + defining Unicode char U+1FAD (decimal 8109) + defining Unicode char U+1FAE (decimal 8110) + defining Unicode char U+1FAF (decimal 8111) + defining Unicode char U+1FB0 (decimal 8112) + defining Unicode char U+1FB1 (decimal 8113) + defining Unicode char U+1FB2 (decimal 8114) + defining Unicode char U+1FB3 (decimal 8115) + defining Unicode char U+1FB4 (decimal 8116) + defining Unicode char U+1FB6 (decimal 8118) + defining Unicode char U+1FB7 (decimal 8119) + defining Unicode char U+1FB8 (decimal 8120) + defining Unicode char U+1FB9 (decimal 8121) + defining Unicode char U+1FBA (decimal 8122) + defining Unicode char U+1FBB (decimal 8123) + defining Unicode char U+1FBC (decimal 8124) + defining Unicode char U+1FBD (decimal 8125) + defining Unicode char U+1FBE (decimal 8126) + defining Unicode char U+1FBF (decimal 8127) + defining Unicode char U+1FC0 (decimal 8128) + defining Unicode char U+1FC1 (decimal 8129) + defining Unicode char U+1FC2 (decimal 8130) + defining Unicode char U+1FC3 (decimal 8131) + defining Unicode char U+1FC4 (decimal 8132) + defining Unicode char U+1FC6 (decimal 8134) + defining Unicode char U+1FC7 (decimal 8135) + defining Unicode char U+1FC8 (decimal 8136) + defining Unicode char U+1FC9 (decimal 8137) + defining Unicode char U+1FCA (decimal 8138) + defining Unicode char U+1FCB (decimal 8139) + defining Unicode char U+1FCC (decimal 8140) + defining Unicode char U+1FCD (decimal 8141) + defining Unicode char U+1FCE (decimal 8142) + defining Unicode char U+1FCF (decimal 8143) + defining Unicode char U+1FD0 (decimal 8144) + defining Unicode char U+1FD1 (decimal 8145) + defining Unicode char U+1FD2 (decimal 8146) + defining Unicode char U+1FD3 (decimal 8147) + defining Unicode char U+1FD6 (decimal 8150) + defining Unicode char U+1FD7 (decimal 8151) + defining Unicode char U+1FD8 (decimal 8152) + defining Unicode char U+1FD9 (decimal 8153) + defining Unicode char U+1FDA (decimal 8154) + defining Unicode char U+1FDB (decimal 8155) + defining Unicode char U+1FDD (decimal 8157) + defining Unicode char U+1FDE (decimal 8158) + defining Unicode char U+1FDF (decimal 8159) + defining Unicode char U+1FE0 (decimal 8160) + defining Unicode char U+1FE1 (decimal 8161) + defining Unicode char U+1FE2 (decimal 8162) + defining Unicode char U+1FE3 (decimal 8163) + defining Unicode char U+1FE4 (decimal 8164) + defining Unicode char U+1FE5 (decimal 8165) + defining Unicode char U+1FE6 (decimal 8166) + defining Unicode char U+1FE7 (decimal 8167) + defining Unicode char U+1FE8 (decimal 8168) + defining Unicode char U+1FE9 (decimal 8169) + defining Unicode char U+1FEA (decimal 8170) + defining Unicode char U+1FEB (decimal 8171) + defining Unicode char U+1FEC (decimal 8172) + defining Unicode char U+1FED (decimal 8173) + defining Unicode char U+1FEE (decimal 8174) + defining Unicode char U+1FEF (decimal 8175) + defining Unicode char U+1FF2 (decimal 8178) + defining Unicode char U+1FF3 (decimal 8179) + defining Unicode char U+1FF4 (decimal 8180) + defining Unicode char U+1FF6 (decimal 8182) + defining Unicode char U+1FF7 (decimal 8183) + defining Unicode char U+1FF8 (decimal 8184) + defining Unicode char U+1FF9 (decimal 8185) + defining Unicode char U+1FFA (decimal 8186) + defining Unicode char U+1FFB (decimal 8187) + defining Unicode char U+1FFC (decimal 8188) + defining Unicode char U+1FFD (decimal 8189) + defining Unicode char U+1FFE (decimal 8190) + defining Unicode char U+2013 (decimal 8211) + defining Unicode char U+2014 (decimal 8212) + defining Unicode char U+2018 (decimal 8216) + defining Unicode char U+2019 (decimal 8217) + defining Unicode char U+201A (decimal 8218) + defining Unicode char U+2030 (decimal 8240) + defining Unicode char U+2039 (decimal 8249) + defining Unicode char U+203A (decimal 8250) + defining Unicode char U+20AC (decimal 8364) + defining Unicode char U+2126 (decimal 8486) + defining Unicode char U+10144 (decimal 65860) + defining Unicode char U+10145 (decimal 65861) + defining Unicode char U+10146 (decimal 65862) + defining Unicode char U+10147 (decimal 65863) +) +(/usr/share/texlive/texmf-dist/tex/latex/greek-fontenc/greek-fontenc.def +File: greek-fontenc.def 2020/10/30 2.0 Common Greek font encoding definitions +)) +LaTeX Info: Redefining \& on input line 125. +)) +(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +Package: inputenc 2021/02/14 v1.3d Input encoding file +\inpenc@prehook=\toks16 +\inpenc@posthook=\toks17 +) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2021/10/15 v2.17l AMS math features +\@mathmargin=\skip49 + +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2021/08/26 v2.01 AMS text + +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen140 +)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen141 +) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 2021/08/26 v2.02 operator names +) +\inf@bad=\count198 +LaTeX Info: Redefining \frac on input line 234. +\uproot@=\count199 +\leftroot@=\count266 +LaTeX Info: Redefining \overline on input line 399. +\classnum@=\count267 +\DOTSCASE@=\count268 +LaTeX Info: Redefining \ldots on input line 496. +LaTeX Info: Redefining \dots on input line 499. +LaTeX Info: Redefining \cdots on input line 620. +\Mathstrutbox@=\box50 +\strutbox@=\box51 +\big@size=\dimen142 +LaTeX Font Info: Redeclaring font encoding OML on input line 743. +LaTeX Font Info: Redeclaring font encoding OMS on input line 744. +\macc@depth=\count269 +\c@MaxMatrixCols=\count270 +\dotsspace@=\muskip16 +\c@parentequation=\count271 +\dspbrk@lvl=\count272 +\tag@help=\toks19 +\row@=\count273 +\column@=\count274 +\maxfields@=\count275 +\andhelp@=\toks20 +\eqnshift@=\dimen143 +\alignsep@=\dimen144 +\tagshift@=\dimen145 +\tagwidth@=\dimen146 +\totwidth@=\dimen147 +\lineht@=\dimen148 +\@envbody=\toks21 +\multlinegap=\skip50 +\multlinetaggap=\skip51 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2938. +LaTeX Info: Redefining \] on input line 2939. +) +(/usr/share/texlive/texmf-dist/tex/latex/chngcntr/chngcntr.sty +Package: chngcntr 2018/04/09 v1.1a change counter resetting +Package chngcntr Info: \counterwithout already defined. +(chngcntr) Quitting chngcntr on input line 21. +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks23 +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2021/03/04 v1.4d Standard LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2021/08/11 v1.11 sin cos tan (DPC) +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/graphics.cfg +File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration +) +Package graphics Info: Driver file: pdftex.def on input line 107. + +(/usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def +File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex +)) +\Gin@req@height=\dimen149 +\Gin@req@width=\dimen150 +) +(/usr/share/texlive/texmf-dist/tex/latex/caption/subcaption.sty +Package: subcaption 2020/10/07 v1.3j Sub-captions (AR) + +(/usr/share/texlive/texmf-dist/tex/latex/caption/caption.sty +Package: caption 2020/10/26 v3.5g Customizing captions (AR) + +(/usr/share/texlive/texmf-dist/tex/latex/caption/caption3.sty +Package: caption3 2020/10/21 v2.2e caption3 kernel (AR) +\captionmargin=\dimen151 +\captionmargin@=\dimen152 +\captionwidth=\dimen153 +\caption@tempdima=\dimen154 +\caption@indent=\dimen155 +\caption@parindent=\dimen156 +\caption@hangindent=\dimen157 +Package caption Info: Standard document class detected. +) +\c@caption@flags=\count276 +\c@continuedfloat=\count277 +) +\c@subfigure=\count278 +\c@subtable=\count279 +) +(/usr/share/texlive/texmf-dist/tex/latex/placeins/placeins.sty +Package: placeins 2005/04/18 v 2.2 +) +(/usr/share/texlive/texmf-dist/tex/latex/tools/verbatim.sty +Package: verbatim 2020-07-07 v1.5u LaTeX2e package for verbatim enhancements +\every@verbatim=\toks24 +\verbatim@line=\toks25 +\verbatim@in@stream=\read3 +) +(/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2020/01/12 v1.61803398 Publication quality tables +\heavyrulewidth=\dimen158 +\lightrulewidth=\dimen159 +\cmidrulewidth=\dimen160 +\belowrulesep=\dimen161 +\belowbottomsep=\dimen162 +\aboverulesep=\dimen163 +\abovetopsep=\dimen164 +\cmidrulesep=\dimen165 +\cmidrulekern=\dimen166 +\defaultaddspace=\dimen167 +\@cmidla=\count280 +\@cmidlb=\count281 +\@aboverulesep=\dimen168 +\@belowrulesep=\dimen169 +\@thisruleclass=\count282 +\@lastruleclass=\count283 +\@thisrulewidth=\dimen170 +) +Package babel Info: Making ; an active character on input line 19. + +(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def +File: l3backend-pdftex.def 2022-01-12 L3 backend support: PDF output (pdfTeX) +\l__color_backend_stack_int=\count284 +\l__pdf_internal_box=\box52 +) +(./lab1_part123_report.aux +LaTeX Font Info: Trying to load font information for LGR+cmr on input line 5 +. + +(/usr/share/texlive/texmf-dist/tex/latex/cbfonts-fd/lgrcmr.fd +File: lgrcmr.fd 2017/07/29 v1.2 Greek European Computer Regular +) + +LaTeX Warning: Label `fig:up' multiply defined. + + +LaTeX Warning: Label `sub@fig:up' multiply defined. + + +LaTeX Warning: Label `fig:cells-multiscale-ii' multiply defined. + + +LaTeX Warning: Label `sub@fig:cells-multiscale-ii' multiply defined. + + +LaTeX Warning: Label `tab:mytable' multiply defined. + +) +\openout1 = `lab1_part123_report.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. +LaTeX Font Info: Checking defaults for LGR/cmr/m/n on input line 32. +LaTeX Font Info: ... okay on input line 32. + (/usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +\scratchcounter=\count285 +\scratchdimen=\dimen171 +\scratchbox=\box53 +\nofMPsegments=\count286 +\nofMParguments=\count287 +\everyMPshowfont=\toks26 +\MPscratchCnt=\count288 +\MPscratchDim=\dimen172 +\MPnumerator=\count289 +\makeMPintoPDFobject=\count290 +\everyMPtoPDFconversion=\toks27 +) (/usr/share/texlive/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty +Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf +Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4 +85. + +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg +File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv +e +)) +Package caption Info: Begin \AtBeginDocument code. +Package caption Info: End \AtBeginDocument code. +LaTeX Font Info: Trying to load font information for LGR+cmtt on input line +33. + +(/usr/share/texlive/texmf-dist/tex/latex/cbfonts-fd/lgrcmtt.fd +File: lgrcmtt.fd 2017/07/29 v1.2 Greek European Computer Typewriter +) [1 + +{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./lab1_part123_report.toc +) +\tf@toc=\write3 +\openout3 = `lab1_part123_report.toc'. + + [2] +Overfull \hbox (14.14018pt too wide) in paragraph at lines 43--44 +\LGR/cmr/m/n/10 Oi ei-knec ei-sdou dh-miour-go-ntai dia-bzo-ntac thn de-do- +mnh ei-kna ''[]\OT1/cmr/m/n/10 edgetest[]23.png[]\LGR/cmr/m/n/10 `` + [] + +[3] +Overfull \hbox (3.9925pt too wide) in paragraph at lines 99--99 +[]\LGR/cmr/bx/n/12 Axiolghsh twn A-po-te-le-smtwn A-nsqneu-shc Ak- + [] + + +Overfull \hbox (13.00157pt too wide) in paragraph at lines 119--120 +\LGR/cmr/m/n/10 Paratjentai ta a-po-te-lsma-ta e-far-mo-gc thc me-jdou sthn + ei-knac []\OT1/cmr/m/n/10 ed-getest[]23.png[]\LGR/cmr/m/n/10 . + [] + +<../image-plots/edgetest_23.png, id=27, 513.92pt x 513.92pt> +File: ../image-plots/edgetest_23.png Graphic file (type png) + +Package pdftex.def Info: ../image-plots/edgetest_23.png used on input line 123 +. +(pdftex.def) Requested size: 172.5pt x 172.50342pt. + +LaTeX Warning: `h' float specifier changed to `ht'. + +<../image-plots/edges-intro0.jpg, id=28, 462.528pt x 346.896pt> +File: ../image-plots/edges-intro0.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/edges-intro0.jpg used on input line 12 +9. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +[4] [5 <../image-plots/edgetest_23.png> <../image-plots/edges-intro0.jpg>] +File: ../image-plots/edges-intro0.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/edges-intro0.jpg used on input line 14 +7. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. +<../image-plots/kyoto_edges.jpg, id=36, 803.0pt x 536.0025pt> +File: ../image-plots/kyoto_edges.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/kyoto_edges.jpg used on input line 179 +. +(pdftex.def) Requested size: 172.5pt x 115.14014pt. + +[6] +<../image-plots/edges-real.jpg, id=41, 462.528pt x 346.896pt> +File: ../image-plots/edges-real.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/edges-real.jpg used on input line 185. + +(pdftex.def) Requested size: 310.4979pt x 232.8849pt. + [7 <../image-plots/kyoto_edges.jpg> <../image-plots/edges-real.jpg>] +<../image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg, id=46, 5 +83.17876pt x 233.87375pt> +File: ../image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg Grap +hic file (type jpg) + +Package pdftex.def Info: ../image-plots/images-scaled/corner-detection-eigenval +ues-scaled.jpg used on input line 233. +(pdftex.def) Requested size: 345.0pt x 138.35901pt. + +[8 <../image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg>] +<../image-plots/corner-detection.jpg, id=51, 462.528pt x 346.896pt> +File: ../image-plots/corner-detection.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/corner-detection.jpg used on input lin +e 260. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + +[9 <../image-plots/corner-detection.jpg>] +<../image-plots/corner-detection-multiscale.jpg, id=55, 462.528pt x 346.896pt> +File: ../image-plots/corner-detection-multiscale.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/corner-detection-multiscale.jpg used o +n input line 289. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + [10 <../image-plots/corner-detection-multiscale.jpg>] +<../image-plots/up.png, id=59, 999.735pt x 563.10374pt> +File: ../image-plots/up.png Graphic file (type png) + +Package pdftex.def Info: ../image-plots/up.png used on input line 322. +(pdftex.def) Requested size: 172.5pt x 97.16127pt. +<../image-plots/cells.jpg, id=61, 242.9075pt x 208.78pt> +File: ../image-plots/cells.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/cells.jpg used on input line 328. +(pdftex.def) Requested size: 138.00052pt x 118.6108pt. + +Overfull \hbox (2.22168pt too wide) in paragraph at lines 320--332 +[]$[]$ $[]$ + [] + +[11 <../image-plots/up.png> <../image-plots/cells.jpg>] +<../image-plots/images-scaled/blob-detection-up-scaled.jpg, id=69, 545.03625pt +x 303.1325pt> +File: ../image-plots/images-scaled/blob-detection-up-scaled.jpg Graphic file (t +ype jpg) + +Package pdftex.def Info: ../image-plots/images-scaled/blob-detection-up-scaled. +jpg used on input line 340. +(pdftex.def) Requested size: 345.0pt x 191.87643pt. +<../image-plots/images-scaled/blob-detection-cells-bad-scaled.jpg, id=70, 515.9 +275pt x 412.54124pt> +File: ../image-plots/images-scaled/blob-detection-cells-bad-scaled.jpg Graphic +file (type jpg) + +Package pdftex.def Info: ../image-plots/images-scaled/blob-detection-cells-bad- +scaled.jpg used on input line 356. +(pdftex.def) Requested size: 169.0519pt x 135.17592pt. +<../image-plots/images-scaled/blob-detection-cells-good-scaled.jpg, id=71, 514. +92375pt x 411.5375pt> +File: ../image-plots/images-scaled/blob-detection-cells-good-scaled.jpg Graphic + file (type jpg) + +Package pdftex.def Info: ../image-plots/images-scaled/blob-detection-cells-good +-scaled.jpg used on input line 362. +(pdftex.def) Requested size: 169.0519pt x 135.10448pt. + [12 <../image-plots/images-scaled/blob-detection-up-scaled.jpg> <../image-plot +s/images-scaled/blob-detection-cells-bad-scaled.jpg> <../image-plots/images-sca +led/blob-detection-cells-good-scaled.jpg>] +<../image-plots/images-scaled/cells-gray-scaled.jpg, id=75, 500.87125pt x 400.4 +9625pt> +File: ../image-plots/images-scaled/cells-gray-scaled.jpg Graphic file (type jpg +) + +Package pdftex.def Info: ../image-plots/images-scaled/cells-gray-scaled.jpg us +ed on input line 373. +(pdftex.def) Requested size: 276.00105pt x 220.70139pt. +<../image-plots/blob-detection-multiscale-up.jpg, id=76, 462.528pt x 346.896pt> + +File: ../image-plots/blob-detection-multiscale-up.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-up.jpg used +on input line 388. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[13 <../image-plots/images-scaled/cells-gray-scaled.jpg>] +<../image-plots/blob-detection-multiscale-cells-bad.jpg, id=81, 462.528pt x 346 +.896pt> +File: ../image-plots/blob-detection-multiscale-cells-bad.jpg Graphic file (type + jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-cells-bad.jpg + used on input line 402. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. +<../image-plots/blob-detection-multiscale-cells-good.jpg, id=82, 462.528pt x 34 +6.896pt> +File: ../image-plots/blob-detection-multiscale-cells-good.jpg Graphic file (typ +e jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-cells-good.jp +g used on input line 408. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + + +LaTeX Warning: Float too large for page by 24.5267pt on input line 414. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[14 <../image-plots/blob-detection-multiscale-up.jpg>] [15 <../image-plots/blob +-detection-multiscale-cells-bad.jpg> <../image-plots/blob-detection-multiscale- +cells-good.jpg>] +<../image-plots/blob-detection-ii-up.jpg, id=89, 462.528pt x 346.896pt> +File: ../image-plots/blob-detection-ii-up.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-ii-up.jpg used on input + line 432. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. +<../image-plots/blob-detection-ii-cells.jpg, id=90, 462.528pt x 346.896pt> +File: ../image-plots/blob-detection-ii-cells.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-ii-cells.jpg used on in +put line 437. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + + +LaTeX Warning: Float too large for page by 24.5267pt on input line 443. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[16 + +] [17 <../image-plots/blob-detection-ii-up.jpg> <../image-plots/blob-detection- +ii-cells.jpg>] +<../image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg, id=10 +1, 543.02875pt x 311.1625pt> +File: ../image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg G +raphic file (type jpg) + +Package pdftex.def Info: ../image-plots/images-scaled/blob-detection-multiscale +-ii-up-scaled.jpg used on input line 453. +(pdftex.def) Requested size: 241.49895pt x 138.38379pt. +<../image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jpg, id +=102, 490.83376pt x 414.54875pt> +File: ../image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jp +g Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/images-scaled/blob-detection-multiscale +-ii-cells-scaled.jpg used on input line 458. +(pdftex.def) Requested size: 241.49895pt x 203.96562pt. + [18 + + <../image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg> <../ +image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jpg>] +File: "avg_scale_errors.txt" (verbatim) +File: "avg_theta_errors.txt" (verbatim) + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[19 + +] [20] +File: "../part3/mean_acc_bovw/mean_acc_results_sorted.txt" (verbatim) +File: "../part3/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt" (verbatim) + +File: "../part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt" (v +erbatim) + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[21] +Overfull \hbox (13.02214pt too wide) in paragraph at lines 560--571 + [][][] + [] + +[22] +<../image-plots/grad-comparison.png, id=120, 462.528pt x 346.896pt> +File: ../image-plots/grad-comparison.png Graphic file (type png) + +Package pdftex.def Info: ../image-plots/grad-comparison.png used on input line + 584. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + [23 <../image-plots/grad-comparison.png>] (./lab1_part123_report.aux) + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 5927 strings out of 480171 + 105803 string characters out of 5894489 + 395164 words of memory out of 5000000 + 23790 multiletter control sequences out of 15000+600000 + 482330 words of font info for 58 fonts, out of 8000000 for 9000 + 59 hyphenation exceptions out of 8191 + 67i,11n,77p,2144b,560s stack positions out of 5000i,500n,10000p,200000b,80000s + + +Output written on lab1_part123_report.pdf (23 pages, 2263691 bytes). +PDF statistics: + 229 PDF objects out of 1000 (max. 8388607) + 128 compressed objects within 2 object streams + 0 named destinations out of 1000 (max. 500000) + 106 words of extra memory for PDF output out of 10000 (max. 10000000) + diff --git a/lab1/report/lab1_part123_report.pdf b/lab1/report/lab1_part123_report.pdf new file mode 100644 index 0000000..5cc92fc Binary files /dev/null and b/lab1/report/lab1_part123_report.pdf differ diff --git a/lab1/report/lab1_part123_report.tex b/lab1/report/lab1_part123_report.tex new file mode 100644 index 0000000..3e44e32 --- /dev/null +++ b/lab1/report/lab1_part123_report.tex @@ -0,0 +1,591 @@ +\documentclass{article} +\usepackage[english,greek, main=greek]{babel} +\usepackage[utf8]{inputenc} + +\usepackage{amsmath} +\usepackage{chngcntr} +\counterwithin{equation}{section} + +\usepackage{graphicx} +\usepackage{subcaption} +\usepackage{placeins} + +\usepackage{verbatim} +\usepackage{booktabs} + +\newcommand{\eng}[1]{\foreignlanguage{english}{#1}} +\newcommand{\Alpha}{\mathrm{A}} + +\useshorthands{;} +\defineshorthand{;}{?} + +\title{Όραση Υπολογιστών\\ + \large Εργαστήριο 1} +\author{Αναστάσιος Στέφανος Αναγνώστου\\ + \texttt{03119051} + \and + Σπυρίδων Παπαδόπουλος\\ + \texttt{03119058}} + +\date{7 Απριλίου 2023} + +\begin{document} +\maketitle + +\newpage +\tableofcontents +\newpage + +\section{Μέρος 1ο} + +\subsection{Δημιουργία Εικόνων Εισόδου} + +Οι εικόνες εισόδου δημιουργούνται διαβάζοντας την δεδομένη εικόνα ''\eng{edgetest\_23.png}`` και προσθέτοντας θόρυβο σε αυτήν. Προστίθεται αντιστοίχως θόρυβος με \eng{PSNR} 20\eng{dB} και θόρυβος με \eng{PSNR} 10\eng{dB}. Αξιοσημειώτο είναι, ότι ο πρώτος θόρυβος είναι στην πραγματικότητα λιγότερος από τον δεύτερον. Το \eng{PSNR} ορίζεται ως εξής: + +\begin{equation} + \begin{gathered} + PSNR = 20\log_{10} \left(\frac{I_{max}-I_{min}}{\sigma_n} \right)(dB),\\ + I_{max} = \underset{x,y} {\max} I(x,y), I_{min} = \underset{x,y} {\min} I(x,y) + \end{gathered} +\end{equation} + +Φαίνεται ότι από τον ορισμό μπορεί να ληφθεί η μεταβλητότητα του θορύβου, βάσει της οποίας τελικά αυτός ορίζεται. Από την έκφραση της μεταβλητότας, μάλιστα, φαίνεται ότι, όσο μεγαλύτερο το \eng{PSNR} σε \eng{dB} τόσο μικρότερη είναι τελικά η μεταβλητότητα του θορύβου, πράγμα που επαληθεύει τα προαναφερθέντα. + +\begin{equation} + \sigma_n = \frac{\left(I_{max}-I_{min}\right)}{10^{\frac{PSNR}{20}}} +\end{equation} + +\subsection{Υλοποίηση Αλγορίθμων Ανίχνευσης Ακμών} + +Η συνάρτηση που θα αναπτυχθεί εφαρμόζει είτε γραμμική είτε μη γραμμική μέθοδο ανίχνευσης ακμών. + +\subsubsection{Γραμμική Μέθοδος} + +Η μεν γραμμική μέθοδος επιχειρεί την προσέγγιση της λαπλασιανής της εξομαλυμένης εικόνας χρήσει γραμμικών φίλτρων. Συγκεκριμένα, σύμφωνα με την γραμμική μέθοδο: + +\begin{equation} + L = \nabla^2 \left(G_{\sigma} * I\right) = \left( \nabla^2 G_{\sigma} \right) * I +\end{equation} + +\subsubsection{Μη Γραμμική Μέθοδος} + +Η δε μη γραμμική μέθοδος επιχειρεί την προσέγγιση της λαπλασιανής της εξομαλυμένης εικόνας χρήσει μορφολογικών τελεστών. Συγκεκριμένα, σύμφωνα με την μη γραμμική μέθοδο: + +\begin{equation} + \begin{gathered} + I_{\sigma} = G_{\sigma} * I, \\ + L = I_{\sigma} \oplus B + I_{\sigma} \ominus B - 2I_{\sigma} + \end{gathered} +\end{equation} + +Αμφότερες οι μέθοδοι, στην συνέχεια, προσεγγίζουν τα σημεία μηδενισμού της λαπλασιανής. Το κάνουν αυτό δημιουργόντας από την λαπλασιανή μία δυαδική εικόνα και βρίσκοντας στην συνέχεια το περίγραμμά της. Τα σημεία μηδενισμού είναι τα σημεία στα οποία το περίγραμμα έχει μοναδιαία τιμή. + +\begin{equation} + \begin{gathered} + X = (L >= 0)\\ + Y = (X \oplus B) - (X \ominus B)\\ + (i, j) = \arg \left| Y = 1 \right| + \end{gathered} +\end{equation} + +Επειδή, όμως, το κριτήριο αυτό επιστρέφει και σημεία τα οποία δεν ανήκουν σε πραγματικές ακμές, τελικά επιλέγονται τα σημεία αυτά στα οποία η εξομαλυμένη εικόνα παρουσιάζει μεγάλη κλίση: + +\begin{equation} + Y[i, j] = 1 \wedge \lVert \nabla I_{\sigma}[i,j] \rVert > \theta_{edge} \cdot \underset{x, y} \max \lVert \nabla I_{\sigma} \rVert +\end{equation} + +Η ποιότητα της ανίχνευσης ακμών εξαρτάται από την επιλογή των παραμέτρων $\sigma, \theta_{edge}$, δηλαδή αντιστοίχως της παραμέτρου εξομάλυνσης και του κατωφλιού για την αποδοχή μίας ακμής. + +\subsection{Αξιολόγηση των Αποτελεσμάτων Ανίσχνευσης Ακμών} + +Για να αξιολόγηση των αποτελεσμάτων της συνάρτησης, πρέπει να οριστεί ένα ποιοτικό κριτήριο. Εν προκειμένω ορίζεται ο μέσος όρος μεταξύ των αληθώς ανισχνευθεισών ακμών και των ψευδών ανιχνευθεισών ακμών. Φυσικά, είναι αναγκαία η πληροφορία των αληθινών ακμών. Αυτές βρίσκονται από την αυθεντική, μη θορυβημένη εικόνα, χρήσει ενώ κατωφλιού ως εξής: + +\begin{equation} + M = (I \oplus B) - (I \ominus B) \Rightarrow \\ + T = (M > \theta_{real}) +\end{equation} + +Δεδομένων, λοιπόν, των αληθινών ακμών, το ποιοτικό κριτήριο διατυπώνεται ως: + +\begin{equation} + \begin{gathered} + C = \frac{Pr(D|T) + PR(T|D)}{2}, \\ + Pr(T|D) = \frac{\lVert D \cap T \rVert}{\lVert T \rVert} + \end{gathered} +\end{equation} + +\subsection{Αποτελέσματα Εφαρμογής της Συνάρτησης} + +Παρατίθενται τα αποτελέσματα εφαρμογής της μεθόδου στην εικόνας \eng{edgetest\_23.png}. + +\begin{figure}[h] + \centering + \includegraphics[width=0.5\textwidth]{../image-plots/edgetest_23.png} + \caption{Η δεδομένη εικόνα εισόδου} + \label{fig:edge-test} +\end{figure} + +\begin{figure}[h!] + \includegraphics[width=\textwidth]{../image-plots/edges-intro0.jpg} + \caption{Θόρυβος \eng{PSNR} 10\eng{dB}} + \label{fig:noise 10db} +\end{figure} +\FloatBarrier + +Όταν η εικόνα \ref{fig:edge-test} θορυβήθηκε με θόρυβο 10 \eng{dB PSNR}, τα αποτελέσματα ήταν αυτά που φαίνονται στην \ref{fig:noise 10db} και οι βαθμολογίες στο κριτήριο ποιότητας οι ακόλουθες: + +\begin{equation} + \begin{gathered} + C_{10db-lin} = 0.6182010279466628\\ + C_{10db-non} = 0.7362110886293316\\ + \end{gathered} +\end{equation} + +Ενώ όταν η εικόνα θορυβήθηκε με θόρυβο 20 \eng{dB PSNR}, τα αποτελέσματα ήταν: + +\begin{figure}[h] + \includegraphics[width=\textwidth]{../image-plots/edges-intro0.jpg} + \caption{Θόρυβος \eng{PSNR} 20\eng{dB}} +\end{figure} +\FloatBarrier + +Με κριτήριο ποιότητας: + +\begin{equation} + \begin{gathered} + C_{20db-lin} = 0.9375887192342924\\ + C_{20db-non} = 0.9671201094187654\\ + \end{gathered} +\end{equation} + +Τα αποτελέσματα επιτεύχθηκαν με τις ακόλουθες παράμετρους: + +\begin{equation} + \begin{gathered} + \sigma = \begin{bmatrix}3 & 1.5 \end{bmatrix}, + \theta = \begin{bmatrix}0.2 & 0.2 \end{bmatrix}, + \theta_{real} = 0,08\\ + \end{gathered} +\end{equation} + +Παρατηρείται ότι η επίδραση του θορύβου είναι καθοριστική, καθώς στην εικόνα με τον λίγοτερο θόρυβο επιτυγχάνεται καλύτερη βαθμολογία στο ποιοτικό κριτήριο. Επίσης, φαίνεται ότι η μη γραμμική μέθοδος πετυχαίνει καλύτερα αποτελέσματα σε κάθε περίπτωση. + +\subsection{Εφαρμογή των Αλγορίθμων Ανίχνευσης Ακμών σε Πραγματικές Εικόνες} + +Η ίδια συνάρτηση χρησιμοποιήθηκε και για την ανίχνευση ακμών στην πραγματική εικόνα του \eng{Kyoto}, όπως φαίνεται στην εικόνα \ref{fig:kyoto}. + +\begin{figure}[h] + \centering + \includegraphics[width=0.5\textwidth]{../image-plots/kyoto_edges.jpg} + \caption{Η πραγματική φωτογραφιά του \eng{Kyoto}} + \label{fig:kyoto} +\end{figure} +\begin{figure}[h] + \centering + \includegraphics[width=0.9\textwidth]{../image-plots/edges-real.jpg} + \caption{Ανίχνευση ακμών στην πραγματική φωτογραφιά του \eng{Kyoto}} + \label{fig:kyoto-edges} +\end{figure} +\FloatBarrier + +Η επεξεργασία έγινε με τις παραμέτρους: + +\begin{equation} + \begin{gathered} + \sigma = 0.3, \theta = 0.2, \theta_{real} = 0.23 \\ + \end{gathered} +\end{equation} + +και πέτυχε τις βαθμολογίες: + +\begin{equation} + \begin{gathered} + C_{lin} = 0.818604135617401\\ + C_{non} = 0.8188562865181751 + \end{gathered} +\end{equation} + +Τα δε οπτικά αποτελέσματα φαίνονται στην εικόνα \ref{fig:kyoto-edges}. Τόσο από την βαθμολογία στο ποιοτικό κριτήριο όσο και οπτικά, φαίνεται ότι αμφότερες η γραμμική και η μη γραμμική μέθοδος έδωσαν πολύ καλά αποτελέσματα. + +\section{Μέρος 2ο} + +Στο σημείο αυτό της εργασίας θα επιχειρηθεί η ανίχνευση διαφόρων χαρακτηριστικών, τόσο σε μία μόνο κλίμακα όσο και σε πολλαπλές κλίμακες. + +\subsection{Ανίχνευση Γωνιών} + +Πρώτα επιχειρείται ανίχνευση γωνιών. Θα παρουσιαστεί η μεθοδολογία και ταυτοχρόνως τα βήματα της επεξεργασίας, για να γίνει σαφής. + +Αρχικά υπολογίζεται ο δομικός τανυστής \eng{\textbf{J}} και οι ιδιοτιμές του. + +\begin{equation} + \begin{gathered} + J_1(x, y) = G_{\rho} * \left(\frac{\partial I_\sigma}{\partial x} \cdot \frac{\partial I_\sigma}{\partial x} \right)(x, y)\\ + J_2(x, y) = G_{\rho} * \left( \frac{\partial I_\sigma}{\partial x} \cdot \frac{\partial I_\sigma}{\partial y} \right)(x, y)\\ + J_3(x, y) = G_{\rho} * \left( \frac{\partial I_\sigma}{\partial y} \cdot \frac{\partial I_\sigma}{\partial y} \right)(x, y)\\ + \lambda_{\pm}(x, y) = \frac{1}{2} \left(J_1 + J_2 \pm \sqrt{\left (J_1 - J_3\right)^2 + 4J_2^2} \right) + \end{gathered} +\end{equation} + +Οι ιδιοτιμές περιέχουν χρήσιμη πληροφορία σχετικά με τις ακμές και τις γωνίες της εικόνας. Παρακάτω, στην εικόνα \ref{fig:kyoto-eigenvalues}, δίνεται η απεικόνισή τους ως γκρίζες εικόνες. + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/images-scaled/corner-detection-eigenvalues-scaled.jpg} + \caption{Απεικόνιση των ιδιοτιμών της εικόνας ως γκρίζες εικόνες} + \label{fig:kyoto-eigenvalues} +\end{figure} +\FloatBarrier + +Φαίνεται ότι η εικόνα η αντιστοιχούσα στην ιδιοτιμή ''-`` αποτυπώνει έντονα τις απολήξεις του πύργου, δηλαδή τις αιχμηρές γωνίες, ενώ η εικόνα αντιστοιχούσα στην ιδιοτιμή ``+'' αποτυπώνει έντονα τα περιγράμματα, δηλαδή τις ακμές. + +Στην συνέχεια, εξάγεται ένα κριτήριο γωνιότητας συναρτήσει των ιδιοτιμών και μίας σταθεράς $k$: + +\begin{equation} + R(x, y) = \lambda_{-}\lambda_{+} - k\cdot\left(\lambda_{-} + \lambda_{+}\right)^2 +\end{equation} + +Τέλος, επιλέγονται ως γωνίες τα σημεία αυτά τα οποία μεγιστοποιούν το κριτήριο εντός τετραγωνικών παραθύρων και αποδίδουν στο κριτήριο γωνιότητας τιμή μεγαλύτερη από ένα κατώφλι. + +\begin{equation} + \begin{gathered} + R(x, y) > \theta_{corn} \cdot R_{max} + \end{gathered} +\end{equation} + +Το αποτέλεσμα εφαρμογής αυτών των συνθηκών στην εικόνα-κριτήριο $R$, για τις παραμέτρους $\sigma = 2, \rho = 2.5, k = 0.05, \theta_{corn} = 0.1$ είναι το ακόλουθο: + + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/corner-detection.jpg} + \caption{Ανίχνευση γωνιών στην εικόνα \eng{Kyoto}} + \label{fig:kyoto-corners} +\end{figure} +\FloatBarrier + +Φαίνεται ότι έχουν εντοπιστεί με επιτυχία πολλές γωνίες, ειδικά οι αιχμηρές απολίξεις του πύργου αλλά και οι ορθές γωνίες οι σχηματιζόμενες από τους πασάλους των κτιρίτων. Ωστόσο, έχουν αναγνωριστει ως γωνίες και ανεπιθύμητα σημεία, όπως τα κλαδιά του δέντρου. Επομένως, συμπεραίνεται ότι η μέθοδος είναι αποτελεσματική αλλά έχει περιθώριο βελτίωσης. + +\subsection{Πολυκλιμακωτή Ανίχνευση Γωνιών} + +Ένα σημαντικό μειονέκτημα της προηγούμενης μεθόδου ήταν ότι περιοριζόταν σε μία μόνο κλίμακα, αφού δεχόταν μόνο ένα ζευγάρι παραμέτρων $(\sigma, \rho)$. Η ιδέα είναι να εφαρμοσθεί η ίδια μέθοδος Ν φορές, κλιμακώνοντας γεωμετρικά κάθε φορά τις παραμέτρους με μία παραμέτρο κλίμακας $s$. Δηλαδή, η επεξεργασία θα γίνεται με τις παραμέτρους: + + \begin{equation} + \begin{gathered} + \sigma_0, \sigma_1, ..., \sigma_{N-1} = s^{0}\sigma_0, s^{1}\sigma_0, ..., \sigma^{N-1}\sigma_0 \\ + \rho_0, \rho_1, ..., \rho_{N-1} = s^{0}\rho_0, s^{1}\rho_0, ..., \rho^{N-1}\rho_0 + \end{gathered} +\end{equation} + +Λόγω των πολλαπλών κλιμάκων, θα επιλεχθούν πολλά σημεία τα οποία έχουν την ίδια πιθανότητα σφάλματος όπως προηγουμένως. Για αυτόν τον λόγο, επιλέγονται τελικά αυτά τα σημεία-γωνίες τα οποία μεγιστοποιούν κάποιο κριτήριο σε μία περιοχή κλιμάκων. Εν προκειμένω, το κριτήριο επιλέγεται να είναι η κανονικοποιημένη Λαπλασιανή της Γκαουσιανής. + +\begin{equation} + \left| LoG(x, y, \sigma_i) \right| = \sigma_i^2 \left|L_xx(x,y, \sigma_i) + L_yy(x, y, \sigma_i) \right| +\end{equation} + +Ουσιαστικά, το σκεπτικό είναι ότι μία γωνία οφείλει να εντοπίζεται τουλάχιστον σε μία μικρή περιοχή κλιμάκων, όχι μόνο σε μία διακεκριμένη κλίμακα. Το αποτέλεσμα της πολυκλιμακωτής μεθόδου στην ίδια εικόνα φαίνεται παρακάτω: + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/corner-detection-multiscale.jpg} + \caption{Πολυκλιμακωτή ανίχνευση γωνιών στην εικόνα \eng{Kyoto}} + \label{fig:kyoto-corners-multiscale} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι εντοπίζονται λιγότερες γωνίες απ'ό,τι προηγουμένως. Επιθεωρώντας την εικόνα, παρατηρείται ότι έπαψαν να εντοπίζονται κάποιες ψεύτικες γωνίες, κυρίως αυτές στα ψιλά κλαδιά του δέντρου, παρασέρνοντας όμως και λίγες πραγματικές, όπως αυτές στον πύργο. Ωστόσο, εξακολουθούν να εντοπίζονται εν πολλοίς οι πραγματικές γωνίες, και μάλιστα με μεγαλύτερη βεβαιότητα, αφού περικλείονται από κύκλους διαφόρων κλιμάκων. Συμπερασματικά, η μέθοδος αυτή είναι σαφώς βελτίωση της προηγούμενης, με αντίτιμο μεγαλύτερη υπολογιστική πολυπλοκότητα. + +\subsection{Ανίχνευση \eng{Blobs}} + +Η ανίχνευση \eng{blobs} αναφέρεται γενικώς στην ανίχνευση περιοχών με κάποια ομοιογένεια. Οι περιοχές αυτές βρίσκονται χρήσει των μερικών παραγώγων δευτέρας τάξεως της εξομαλυμένης εικόνας. Συγκεκριμένα, δεδομένου του Χεσιανού πίνακα: + +\begin{equation} + H(x, y) = \begin{bmatrix} L_{xx}(x, y, \sigma) & L_{xy}(x, y, \sigma) \\ + L_{xy}(x, y, \sigma) & L_{yy}(x, y, \sigma)\end{bmatrix} +\end{equation} + +Το κριτήριο για τον εντοπισμό περιοχών ομοιογένειας είναι απλώς ο μηδενισμός της ορίζουσας: + +\begin{equation} + \begin{gathered} + R(x, y) = \det\left| H(x, y) \right|\\ + (x, y) = \underset{x, y} {\arg} \left( R(x, y) = 0 \right) + \end{gathered} +\end{equation} + +Επομένως, αναπτύσσεται μεθοδολογία πλήρως ανάλογη με την μεθοδολογία για την ανίχνευση ακμών. Δηλαδή, εξομαλύνεται η εικόνα, υπολογίζεται ο Χεσιανός πίνακας και το κριτήριο $R(x, y)$, εντοπίζονται τα σημεία μηδενισμού και επιλέγονται αυτά τα οποία έχουν τιμή στην εικόνα μεγαλύτερη από κάποιο κατώφλι. + +Η μέδοδος εφαρμόζεται στην εικόνα \eng{Up}, από την ομώνυμη ταινία της \eng{Pixar}, και σε μία εικόνα ανθρωπίνων κυττάρων. Πρώτη θα εξεταστεί η εφαρμογή στην εικόνα \eng{Up}. + +\begin{figure}[h] + \begin{subfigure}{.5\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/up.png} + \caption{Η εικόνα \eng{Up}} + \label{fig:up} + \end{subfigure} + \begin{subfigure}{.5\textwidth} + \centering + \includegraphics[width=0.8\textwidth]{../image-plots/cells.jpg} + \caption{Η εικόνα ανθρωπίνων κυττάρων} + \label{fig:up} + \end{subfigure} + \caption{Οι αρχικές εικόνες για την ανίχνευση \eng{blobs}} +\end{figure} +\FloatBarrier + +Παρακάτω, στην εικόνα \ref{fig:up-blobs} φαίνονται τα αποτελέσματα για παραμέτρους $\sigma = 2.5, \theta = 0.005$ + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/images-scaled/blob-detection-up-scaled.jpg} + \caption{Aνίχνευση \eng{blobs} στην εικόνα \eng{Up}} + \label{fig:up-blobs} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι αν και το κατώφλι για την αποδοχή της περιοχής ομοιογένειας είναι πολύ χαμηλό, τα αποτελέσματα είναι πολύ ικανοποιητικά. Συγκεκριμένα, εντοπίζονται οι περιοχές στα μπαλόνια οι οποίες αντανακλούν το φως του ηλίου και έχουν χαρακτηριστική λευκή λάμψη. Επιπλέον, εντοπίζονται οι περιοχές μεταξύ των μπαλονιών στις οποίες υπάρχει σκοτάδι + +Εξετάζεται τώρα η εφαρμογή της μεθόδου στην εικόνα των κυττάρων. + +Τα αποτελέσματα για τις ίδιες παραμέτρους με πριν είναι αυτά που φαίνονται στην εικόνα \ref{fig:cells-bad} + +\begin{figure}[h] + \centering + \begin{subfigure}{.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/images-scaled/blob-detection-cells-bad-scaled.jpg} + \caption{Aνίχνευση \eng{blobs} στην εικόνα ανθρωπίνων κυττάρων χαμηλό κατώφλι} + \label{fig:cells-bad} + \end{subfigure} + \begin{subfigure}{.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/images-scaled/blob-detection-cells-good-scaled.jpg} + \caption{Aνίχνευση \eng{blobs} στην εικόνα ανθρωπίνων κυττάρων υψηλό κατώφλι} + \label{fig:cells-good} + \end{subfigure} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι αν και ανιχνεύονται επιτυχώς μερικές από τις λευκές περιοχές ομοιογένειας, ανιχνεύονται επίσης ανεπιθυμητές περιοχές. Αυτό συμβαίνει, γιατί το περιβάλλον της εικόνας είναι τραχύ, με αποτέλεσμα οποιαδήποτε ομοιογένεια να ξεχωρίζει. Αντιθέτως, ο ουρανός προηγουμένως είναι πολύ ομαλός και ομοιογενής, επομένως δεν ξεχωρίζει. Για αυτόν τον λόγο, προσαρμόζεται η παράμετρος $\theta \leftarrow 0.25$. Τα νέα αποτελέσματα φαίνονται στην εικόνα \ref{fig:cells-good}, όπου πλέον ανιχνεύονται σαφώς λίγοτερες περιοχές ομοιογένειες, αλλά ορθότερες. + +\begin{figure}[h] + \centering + \includegraphics[width=0.8\textwidth]{../image-plots/images-scaled/cells-gray-scaled.jpg} + \caption{Η εικόνα των κυττάρων γκρίζα} + \label{fig:cells-gray} +\end{figure} +\FloatBarrier + +Αξιοσημειώτο είναι το γεγονός ότι οι ερυθρές περιοχές γενικώς δεν ανιχνεύονται, σίγουρα όχι στον ίδιο βαθμό με τις λευκές. Αυτό συμβαίνει γιατί η επεξεργασία γίνεται στην γκρίζα μορφή της εικόνας, επομένως η χρωματική διαφορά απαλείφεται, όπως φαίνεται στην εικόνα \ref{fig:cells-gray}. Εφόσον η υφή είναι η ίδια, ανεξαρτήτως χρώματος, γίνεται σαφές ότι δεν μπορούν να διακριθούν στον ίδιο βαθμό με τις λευκές. Εκτός από αυτό, συμπεραίνεται ότι σε τραχύ περιβάλλον πρέπει να αυξηθεί το κατώφλι αποδοχής σημείων. + +\subsection{Πολυκλιμακωτή Ανίχνευση \eng{Blobs}} + +Για την βελτίωση της μεθόδου χρησιμοποιούνται τώρα πολλαπλές κλίμακες, σε πλήρη αναλογία με την πολυκλιμακωτή ανίχνευση γωνιών. + +Στην εικόνα \ref{fig:up-multiscale} φαίνονται τα αποτελέσματα στην εικόνα \eng{Up} για τις τιμές παραμέτρων $\sigma = 3, \theta = 0.05, s = 1.1, N = 8$. Παρατηρείται ότι εντοπίζονται \eng{blobs} ποικίλλων μεγεθών, στα οποία περιλαμβάνονται τόσο ολόκληρα μπαλόνια όσο και απλές αντανακλάσεις φωτός, όπως προηγουμένως. +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-up.jpg} + \caption{Πολυκλιμακωτή ανίχνευση \eng{blobs} στην εικόνα \eng{Up}} + \label{fig:up-multiscale} +\end{figure} +\FloatBarrier + +Στην εικόνα \ref{fig:cells-multiscale-bad} φαίνεται το αποτέλεσμα της πολυκλιμακωτής ανίχνευσης \eng{blobs} για τις τιμές παραμέτρων $\sigma = 3, \theta = 0.05, s = 1.1, N = 8$. Η ανίχνευση γίνεται σε 8 κλίμακες του $\sigma = 3$ με παράγοντα το 1.1 και χαμηλό κατώφλι.Αντιστοίχως, στην εικόνα \ref{fig:cells-multiscale-good} φαίνεται το αποτέλεσμα της πολυκλιμακωτής ανίχνευσης \eng{blobs} για τις τιμές παραμέτρων $\sigma = 3, \theta = 0.15, s = 1.1, N = 8$. Δηλαδή, η ανίχνευση γίνεται σε 8 κλίμακες του $\sigma = 3$ και με υψηλότερο κατώφλι, με παράγοντα το 1.1. + +Στην δε εικόνα \ref{fig:cells-multiscale-pair} παρατηρείται, ότι μειώνοντας το κατώφλι, όπως και στην μονοκλιμακωτή ανίχνευση, απορρίπτονται επιτυχώς κάποια ανεπιθύμητα \eng{blobs}. Μάλιστα, αυτό γίνεται εν προκειμένω με μεγαλύτερη επιτυχία, καθώς εξακολουθούν να ανιχνεύονται όλες οι λευκές περιοχές. Δεν απορρίπτεται, δηλαδή, κατά λάθος, κάποιο επιθυμητό \eng{blob}. Επομένως, συμπεραίνεται ότι η επέκταση της μεθόδου σε πολλαπλές κλίμακες είναι ευεργετική. + +\begin{figure}[h] + \centering + \begin{subfigure}{\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-cells-bad.jpg} + \caption{Χαμηλό κατώφλι} + \label{fig:cells-multiscale-bad} + \end{subfigure} + \begin{subfigure}{\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-cells-good.jpg} + \caption{Υψηλό κατώφλι} + \label{fig:cells-multiscale-good} + \end{subfigure} + \caption{Πολυκλιμακωτή ανίχνευση \eng{blobs} σε κύτταρα} + \label{fig:cells-multiscale-pair} +\end{figure} +\FloatBarrier + +\subsection{Επιτάχυνση Ανίχνευσης \eng{Blobs}} + +Η παραπάνω μέθοδος μπορεί να επιταχυνθεί \footnote{Σημειώνεται ότι η παρατηρούμενη επιτάχυνση εξαρτάται από την υλοποίηση της απλής μεθόδου ανίχνευσης \eng{blobs}. Βλέπε \ref{section:details}.} χρήσει ολοκληρωτικών εικόνων και \eng{box filter}. Συγκεκριμένα, ο υπολογισμός των μερικών παραγώγων μέχρι στιγμής απαιτούσε την συνέλιξη φίλτρων με την εκάστοτε εικόνα, γεγονός που τον καθιστούσε υπολογιστικά ακριβό. + +Οι ολοκληρωτικές εικόνες είναι μία τεχνική η οποία επιτρέπει των υπολογισμό συνελίξεων με την εικόνα σε χρόνο ανεξάρτητο του πυρήνα και εξαρτώμενο μόνο από το μέγεθος της εικόνας. Αυτό συμβαίνει, γιατί, χρήσει ολοκληρωτικών εικόνων, το άθροισμα των \eng{pixels} μίας ορθογώνιας περιοχής μπορεί να υπολογιστεί σε σταθερό χρόνο. Για να επιτευχθεί, όμως, η επιτάχυνση αυτή, χρησιμοποιείται μία προσέγγιση της παραγώγου. Επομένως, πρόκειται για προσεγγιστική μέθοδο και αναμένονται αποκλίσεις από τα προηγούμενα αποτελέσματα. + +Στην εικόνα \ref{fig:ii} φαίνονται τα αποτελέσματα της απόπειρας επιτάχυνσης της ανίχνευσης \eng{blobs} στις ίδιες εικόνες όπως προηγουμένως, στην οποία χρησιμοποιήθηκαν οι ίδιες ακριβώς παράμετροι όπως και στην απλή μέθοδο. + +Στην εικόνα \ref{fig:up-ii}, όπου χρησιμοποιείται μικρή τιμή της παραμέτρου $\sigma$, τα αποτελέσματα είναι πολύ ικανοποιητικά, καθώς εντοπίζονται επιτυχώς οι αντανακλάσεις φωτός επάνω στα μπαλόνια και, φυσικά, δεν αντιμετωπίζονται εσφαλμένες περιοχές ομοιογένειας. + +Στην δε εικόνα \ref{fig:cells-ii}, όπου χρησιμοποιείται μεγαλύτερη τιμή της παραμέτρου $\sigma$, τα αποτελέσματα δεν είναι το ίδιο ικανοποιητικά. Συγκεκριμένα, παρατηρείται ότι ανιχνεύονται μερικά ανεπιθύμητα \eng{blobs}, ωστόσο ανιχνεύονται και μερικά ορθώς. Επομένως, είναι εμφανές το γεγονός ότι η επιτάχυνση οφείλεται σε προσέγγιση. + +\begin{figure}[h] + \centering + \begin{subfigure}{\textwidth} + \includegraphics[width=\textwidth]{../image-plots/blob-detection-ii-up.jpg} + \caption{Αποτέλεσμα στην εικόνα \eng{Up}} + \label{fig:up-ii} + \end{subfigure} + \begin{subfigure}{\textwidth} + \includegraphics[width=\textwidth]{../image-plots/blob-detection-ii-cells.jpg} + \caption{Αποτέλεσμα στην εικόνα κυττάρων} + \label{fig:cells-ii} + \end{subfigure} + \caption{Προσέγγιση ανίχνευσης \eng{blobs} με ολοκληρωτικές εικόνες} + \label{fig:ii} +\end{figure} +\FloatBarrier + +\subsection{Επιτάχυνση Πολυκλιμακωτής Ανίχνευση \eng{Blobs}} + +Τα ίδια συμπεράσματα προκύπτουν και για την πολυκλιμακωτή ανίχνευση. + +\begin{figure}[h] + \centering + \begin{subfigure}{0.7\textwidth} + \includegraphics[width=\textwidth]{../image-plots/images-scaled/blob-detection-multiscale-ii-up-scaled.jpg} + \caption{Αποτέλεσμα στην εικόνα \eng{Up}} + \label{fig:cells-multiscale-ii} + \end{subfigure} + \begin{subfigure}{0.7\textwidth} + \includegraphics[width=\textwidth]{../image-plots/images-scaled/blob-detection-multiscale-ii-cells-scaled.jpg} + \caption{Αποτέλεσμα στην εικόνα κυττάρων} + \label{fig:cells-multiscale-ii} + \end{subfigure} + \caption{Προσέγγιση πολυκλιμακωτής ανίχνευσης \eng{blobs} με ολοκληρωτικές εικόνες} +\end{figure} +\FloatBarrier + +\clearpage +\section{Μέρος 3ο} + +Ο κώδικας που χρησιμοποιήθηκε για τα πειράματα παρατίθεται σε ξεχωριστά αρχεία με σχολιασμό και δεν αναλύεται στην αναφορά. + +\subsection{Ταίριασμα Εικόνων υπό Περιστροφή και Αλλαγή Κλίμακας} + +Σε αυτο το μέρος επιχειρείται το ταίριασμα μεταξύ εικόνων και μετασχηματισμών αυτών. Συγκεκριμενά, 3 αυθεντικές εικόνες υπόκεινται σε περιστροφές $(-20^{\circ}, -10^{\circ}, 0^{\circ}, 10^{\circ}, 20^{\circ})$ και σε κλιμακώσεις $(0.6, 0.8, 1.0, 1.2)$. Δεδομένης μίας εικόνας αναφοράς, επιχειρείται η αντιστοίχιση των τοπικών περιγραφητών της με αυτούς των μετασχηματισμένων εικόνων. Σημειώνεται, ότι οι ανιχνευτές είναι: + +\begin{table}[htbp] + \centering + \caption{Αντιστοίχιση μονοκλιμακωτών και πολυκλιμακωτών μεθόδων.} + \begin{tabular}{l|l} + \toprule + Μονοκλιμακωτή & Πολυκλιμακωτή \\ + \midrule + \eng{CornerDetection} & \eng{HarrisLaplacian} \\ + \eng{BlobDetection} & \eng{HessianLaplacian} \\ + - & \eng{BoxLaplacian} \\ + \bottomrule + \end{tabular}% + \label{tab:mytable}% +\end{table}% + +Οι παράμετροι που χρησιμοποιήθηκαν ήταν: + +\begin{equation} + \begin{gathered} + \sigma = 2, \rho = 2.5, \theta = 0.005\\ + k = 0.05, scale = 1.1, N = 6 + \end{gathered} +\end{equation} + +Παρακάτω παρατίθενται τα αποτελέσματα ανά περιγραφητή ανά ανιχνευτή για τις 3 εικόνες. + +\begin{figure}[h] + \selectlanguage{english} + \verbatiminput{avg_scale_errors.txt} + \selectlanguage{greek} + \caption{Σφάλματα Κλίμακας} +\end{figure} +\FloatBarrier + +\begin{figure}[h] + \selectlanguage{english} + \verbatiminput{avg_theta_errors.txt} + \selectlanguage{greek} + \caption{Σφάλματα Γωνίας} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι οι περιγραφητές \eng{SURF} αποδίδουν κατά πολύ καλύτερα από τους περιγραφητές \eng{HOG}. Αυτό είναι αναμενόμενο, αφού εξάγουν περιστροφικά και ως προς την κλίμακα ανεξάρτητους περιγραφητές. + +Με \eng{BEST} επισημειώνεται το ζευγάρι περιγραφητή και ανιχνευτή το οποίο έχει το ελάχιστο μέσο σφάλμα στις 3 εικόνες. Παρατηρείται, τόσο στην γωνία όσο και στην κλίμακα είναι το ζευγάρι πολυκλιμακωτής ανίχνευσης \eng{blobs} με \eng{SURF}. Αυτό είναι αναμενόμενο, αφού τα \eng{blobs} είναι γενικές περιοχές ομοιομορφίας και δεν αλλοιώνονται τόσο με την περιστροφή, σε αντίθεση με τις γωνίες, οι οποίες μπορούν να συμπέσουν πιο εύκολα με άλλες γωνίες και να επικρατήσει σύγχυση. Αξιοσημείωτο είναι, ότι το ζευγάρι αυτό είναι και από τα πιο χρονοβόρα, ενώ η αντίστοιχη υλοποίηση χρήσει ολοκληρωτικών εικόνων και \eng{box filters} (BoxLaplacian) είναι ταχύτερη, αλλά λιγότερο ακριβής, πράγμα αναμενόμενο αφού πρόκειται για προσέγγιση. + +\subsection{Κατηγοριοποίηση Εικόνων} + +Σε αυτό το μέρος επιχειρείται η κατηγοριοποίηση εικόνων βάσει των εξαχθέντων χαρακτηριστικών τους. Συγκεκριμένα, δοκιμάζονται συνδυασμοί περιγραφητών και ανιχνευτών σημείων ενδιαφέροντος για την εξαγωγή χαρακτηριστικών από καθεμία εικόνας καθεμίας κλάσης. Στην συνέχεια, διαχωρίζονται σε σύνολα εκπαίδευσης και επικύρωσης και δημιουργούνται οι ανάλογες ετικέτες ταξινόμησης. + +Για την ταξινόμηση πρέπει να μετατραπούν οι τοπικοί περιγραφητές σε καθολικά διανύσματα. Αυτό επιτυγχάνεται μέσω της αναπαράστασης \eng{Bag of Visual Words}. Συγκεκριμένα, δημιουργείται ένα οπτικό ``λεξικό'' συνενώνοντας τους περιγραφητές του συνόλου εκπαίδευσης και εφαρμόζοντας τον αλγόριθμο συσταδοποίησης \eng{kmeans} σε ένα υποσύνολο αυτών. Έτσι δημιουργούνται κέντρα χαρακτηριστικών. Επόμενο βήμα είναι να μετρηθεί η ευκλίδεια απόσταση καθενός περιγραφητή του συνόλου εκπαίδευσης και επικύρωσης από τα κέντρα αυτά και να επιλεχθεί η ελάχιστη. Τέλος, κατασκευάζεται το ιστόγραμμα της εικόνας βάσει της συχνότητας εμφάνισης των οπτικών λέξεων και κανονικοποιείται. Η ίδια η κατηγοριοποίηση πραγματοποιείται από έναν ταξινομητή \eng{SVM}. + +Παρατίθενται τα αποτελέσματα δοκιμών, χρήσει της προμεταγλωττισμένης συνάρτησης, της υλοποιημέμης συνάρτησης από τους γραφόντες και δύο πλήθων ομάδων + +\begin{figure}[h] + \selectlanguage{english} + \verbatiminput{../part3/mean_acc_bovw/mean_acc_results_sorted.txt} + \selectlanguage{greek} + \caption{Αποτελέσματα Ταξινόμησης (Προμεταγλωττισμένες Συναρτήσεις, 500 ομάδες)} +\end{figure} +\FloatBarrier + +\begin{figure}[h] + \selectlanguage{english} + \verbatiminput{../part3/mean_acc_mybovw/mean_acc_mybovw_results_sorted.txt} + \selectlanguage{greek} + \caption{Αποτελέσματα Ταξινόμησης (Πρωτότυπες Συναρτήσεις, 1000 ομάδες)} +\end{figure} +\FloatBarrier + +\begin{figure}[h] + \selectlanguage{english} + \verbatiminput{../part3/mean_acc_mybovw_500/mean_acc_mybovw_500_results_sorted.txt} + \selectlanguage{greek} + \caption{Αποτελέσματα Ταξινόμησης (Πρωτότυπες Συναρτήσεις, 500 ομάδες)} +\end{figure} +\FloatBarrier + +Γενικώς, παρατηρείται, ότι οι περιγραφητές \eng{HOG} αποδίδουν σταθερά καλύτερα από τους περιγραφητές \eng{SURF}. Παρατηρείται, επίσης, ότι οι πολυκλιμακωτοί ανιχνευτές δεν αποδίδουν σταθερά καλύτερα από τους μονοκλιμακωτούς. Συγκεκριμένα, φαίνεται ότι οι περιγραφητές \eng{HOG} δεν ευνοούνται ιδιαίτερα από την πολυκλιμακωτή ανάλυση, σε αντίθεση με τους \eng{SURF} οι οποίοι ευνοούνται κατά πολύ, όπως φαίνεται στον πίνακα \ref{tab:mytable} εν συντομία \footnote{Για να είναι δίκαια η σύγκριση, έγινε μεταξύ των πρωτότυπων υλοποιήσεων}. Αυτό είναι αναμενομένο, γιατί οι περιγραφητές \eng{SURF} είναι αμετάβλητη ως προς την κλιμάκωση και την περιστροφή. Επομένως, όταν χρησιμοποιούνται με πολυκλιμακωτούς ανιχνευτές, αποδίδουν καλύτερα, γιατί εντοπίζονται περισσότερα συνολικά χαρακτηριστικά στην εικόνα. + +Από κάποιες μικρές διακυμάνσεις δεν μπορούν να εξαχθούν με βεβαιότητα συμπεράσματα, καθώς τα αποτελέσματα εξαρτώνται και από την τυχαία επιλογή χαρακτηριστικών στον kmeans. + +\begin{table}[htbp] + \centering + \caption{Αντιστοίχιση μονοκλιμακωτών και πολυκλιμακωτών μεθόδων για \eng{SURF} περιγραφητή.} + \begin{tabular}{|l|l|l|l|l|l|} + \toprule + Ομάδες & Μονοκλιμακωτή & Επίδοση & Πολυκλιμακωτή & Επίδοση & Διαφορά\\ + \midrule + 500 & \eng{CornerDetection} & 54.621 & \eng{HarrisLaplacian} & 59.310 & 4.689 \\ + 500 & \eng{BlobDetection} & 55.862 & \eng{HessianLaplacian} & 57.103 & 1.241\\ + 1000 & \eng{CornerDetection} & 56.966 & \eng{HarrisLaplacian} & 59.310 & 2.344\\ + 1000 & \eng{BlobDetection} & 54.345 & \eng{HessianLaplacian} & 59.586 & 5.241\\ + \bottomrule + \end{tabular}% + \label{tab:mytable}% +\end{table}% + +Συμπερασματικά, φαίνεται ότι την καλύτερη επίδοση την έχουν, σταθερά, οι περιγραφητές \eng{HOG}, οι οποίοι αποδίδουν κατά 5 με 10 ποσοστιαίες μονάδες καλύτερα από τους \eng{SURF}. Σχετικά με τους ανιχνευτές, οι διαφορές στα αποτελέσματα είναι πολύ μικρές. Στην κορυφή τείνουν να βρίσκονται ο πολυκλιμακωτός ανιχνευτής γωνιών (\eng{HarrisLaplacian}), ο μονοκλιμακωτός ανιχνευτής \eng{blobs} και ο πολυκλιμακωτός ανιχνευτής \eng{blobs} (\eng{HessianLaplacian}). Επομένως, προτείνεται ο συνδυασμός \eng{featuresHOG, HarrisLaplacian}, χωρίς όμως να απορρίπτονται οι άλλοι δύο ανιχνευτές, καθώς αποδίδουν και αυτοί ικανοποιητικά καλά. + +\newpage +\section{Παράρτημα} +\subsection{Επιτάχυνση χρήσει ολοκληρωτικών εικόνων και \eng{box filters}} +\label{section:details} + +Η παρατηρούμενη επιτάχυνση εξαρτάται και από την υλοποίηση της απλής μεθόδου ανίχνευσης \eng{blobs}. Συγκεκριμένα, αν ο υπολογισμός των μερικών παραγώγων είχε γίνει χρήσει ''χειροποίητης`` συνάρτησης συνελίξεως δύο διαστάσεων, τότε η επιτάχυνση γίνεται αμέσως εμφανής. Ωστόσο, αν ο υπολογισμός μερικών παραγώγων είχε γίνει χρήσει έτοιμης συνάρτησης συνέλιξης από την βιβλιοθήκη \eng{cv2}, τότε η επιτάχυνση δεν θα είναι εμφανής. Αυτό συμβαίνει γιατί, κατόπιν μετρήσεων για διάφορες τιμές τις παραμέτρου $\sigma$, παρατηρήθηκε ότι η ταχύτητα της συνάρτησης \eng{cv2.filter2D} ήταν πρακτικά σταθερή. Το ίδιο παρατηρήθηκε και για την υλοποίηση χρήσει ολοκληρωτικών εικόνων και \eng{box filters}. Η δε ''χειροκίνητη`` υλοποίηση της διδιάστασης συνέλιξης εμφάνισε τετραγωνική χρονική εξάρτηση από την παράμετρο $\sigma$, όπως αναμενόταν. Τα συμπεράσματα παρουσιάζονται συνοπτικά στο ακόλουθο γράφημα \ref{fig:grad-comparison}. Αξιοσημειώτο είναι ότι, για την δίκαιη σύγκριση των αποτελεσμάτων, χρησιμοποιήθηκε ο \eng{Just-in-Time} μεταγλωττιστής \eng{Numba} για την βελτιστοποίηση των βρόχων \eng{for} στην υλοποίηση της διδιάστατης συνέλιξης. Παρ'όλα αυτά, η διαφορά στην απόδοση παραμένει σημαντική. + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/grad-comparison.png} + \caption{Σύγκριση ταχύτητας διαφόρων υλοποιήσεων υπολογισμού μερικών παραγώγων} + \label{fig:grad-comparison} +\end{figure} +\FloatBarrier + +\end{document} + diff --git a/lab1/report/lab1_part123_report.toc b/lab1/report/lab1_part123_report.toc new file mode 100644 index 0000000..2f2f76b --- /dev/null +++ b/lab1/report/lab1_part123_report.toc @@ -0,0 +1,41 @@ +\babel@toc {greek}{}\relax +\contentsline {section}{\numberline {1}Μέρος 1ο}{3}{}% +\contentsline {subsection}{\numberline {1.1}Δημιουργία Εικόνων Εισόδου}{3}{}% +\contentsline {subsection}{\numberline {1.2}Υλοποίηση Αλγορίθμων Ανίχνευσης Ακμών}{3}{}% +\contentsline {subsubsection}{\numberline {1.2.1}Γραμμική Μέθοδος}{3}{}% +\contentsline {subsubsection}{\numberline {1.2.2}Μη Γραμμική Μέθοδος}{3}{}% +\contentsline {subsection}{\numberline {1.3}Αξιολόγηση των Αποτελεσμάτων Ανίσχνευσης Ακμών}{4}{}% +\contentsline {subsection}{\numberline {1.4}Αποτελέσματα Εφαρμογής της Συνάρτησης}{4}{}% +\contentsline {subsection}{\numberline {1.5}Εφαρμογή των Αλγορίθμων Ανίχνευσης Ακμών σε Πραγματικές Εικόνες}{7}{}% +\contentsline {section}{\numberline {2}Μέρος 2ο}{8}{}% +\contentsline {subsection}{\numberline {2.1}Ανίχνευση Γωνιών}{8}{}% +\contentsline {subsection}{\numberline {2.2}Πολυκλιμακωτή Ανίχνευση Γωνιών}{10}{}% +\contentsline {subsection}{\numberline {2.3}Ανίχνευση \foreignlanguage {english}{Blobs}}{11}{}% +\contentsline {subsection}{\numberline {2.4}Πολυκλιμακωτή Ανίχνευση \foreignlanguage {english}{Blobs}}{13}{}% +\contentsline {subsection}{\numberline {2.5}Επιτάχυνση Ανίχνευσης \foreignlanguage {english}{Blobs}}{16}{}% +\contentsline {subsection}{\numberline {2.6}Επιτάχυνση Πολυκλιμακωτής Ανίχνευση \foreignlanguage {english}{Blobs}}{18}{}% +\contentsline {section}{\numberline {3}Μέρος 3ο}{19}{}% +\contentsline {subsection}{\numberline {3.1}Ταίριασμα Εικόνων υπό Περιστροφή και Αλλαγή Κλίμακας}{19}{}% +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\contentsline {subsection}{\numberline {3.2}Κατηγοριοποίηση Εικόνων}{20}{}% +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\babel@toc {english}{}\relax +\babel@toc {greek}{}\relax +\contentsline {section}{\numberline {4}Παράρτημα}{23}{}% +\contentsline {subsection}{\numberline {4.1}Επιτάχυνση χρήσει ολοκληρωτικών εικόνων και \foreignlanguage {english}{box filters}}{23}{}% diff --git a/lab1/report/lab1_part12_report.aux b/lab1/report/lab1_part12_report.aux new file mode 100644 index 0000000..16c5cfb --- /dev/null +++ b/lab1/report/lab1_part12_report.aux @@ -0,0 +1,74 @@ +\relax +\providecommand\babel@aux[2]{} +\@nameuse{bbl@beforestart} +\catcode `;\active +\babel@aux{greek}{} +\@writefile{toc}{\contentsline {section}{\numberline {1}Μέρος 1ο}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Δημιουργία Εικόνων Εισόδου}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Υλοποίηση Αλγορίθμων Ανίχνευσης Ακμών}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.1}Γραμμική Μέθοδος}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.2}Μη Γραμμική Μέθοδος}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Αξιολόγηση των Αποτελεσμάτων Ανίσχνευσης Ακμών}{4}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.4}Αποτελέσματα Εφαρμογής της Συνάρτησης}{4}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Η δεδομένη εικόνα εισόδου\relax }}{5}{}\protected@file@percent } +\providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}} +\newlabel{fig:edge-test}{{1}{5}} +\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Θόρυβος \foreignlanguage {english}{PSNR} 10\foreignlanguage {english}{dB}\relax }}{5}{}\protected@file@percent } +\newlabel{fig:noise 10db}{{2}{5}} +\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Θόρυβος \foreignlanguage {english}{PSNR} 20\foreignlanguage {english}{dB}\relax }}{6}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.5}Εφαρμογή των Αλγορίθμων Ανίχνευσης Ακμών σε Πραγματικές Εικόνες}{7}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Η πραγματική φωτογραφιά του \foreignlanguage {english}{Kyoto}\relax }}{7}{}\protected@file@percent } +\newlabel{fig:kyoto}{{4}{7}} +\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Ανίχνευση ακμών στην πραγματική φωτογραφιά του \foreignlanguage {english}{Kyoto}\relax }}{7}{}\protected@file@percent } +\newlabel{fig:kyoto-edges}{{5}{7}} +\@writefile{toc}{\contentsline {section}{\numberline {2}Μέρος 2ο}{8}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Ανίχνευση Γωνιών}{8}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Απεικόνιση των ιδιοτιμών της εικόνας ως γκρίζες εικόνες\relax }}{8}{}\protected@file@percent } +\newlabel{fig:kyoto-eigenvalues}{{6}{8}} +\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Ανίχνευση γωνιών στην εικόνα \foreignlanguage {english}{Kyoto}\relax }}{9}{}\protected@file@percent } +\newlabel{fig:kyoto-corners}{{7}{9}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Πολυκλιμακωτή Ανίχνευση Γωνιών}{10}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Πολυκλιμακωτή ανίχνευση γωνιών στην εικόνα \foreignlanguage {english}{Kyoto}\relax }}{10}{}\protected@file@percent } +\newlabel{fig:kyoto-corners-multiscale}{{8}{10}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Ανίχνευση \foreignlanguage {english}{Blobs}}{11}{}\protected@file@percent } +\newlabel{fig:up}{{9{\greekscript \textalpha \textnumeralsigngreek }}{11}} +\newlabel{sub@fig:up}{{{\greekscript \textalpha \textnumeralsigngreek }}{11}} +\newlabel{fig:up}{{9{\greekscript \textbeta \textnumeralsigngreek }}{11}} +\newlabel{sub@fig:up}{{{\greekscript \textbeta \textnumeralsigngreek }}{11}} +\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Οι αρχικές εικόνες για την ανίχνευση \foreignlanguage {english}{blobs}\relax }}{11}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Aνίχνευση \foreignlanguage {english}{blobs} στην εικόνα \foreignlanguage {english}{Up}\relax }}{12}{}\protected@file@percent } +\newlabel{fig:up-blobs}{{10}{12}} +\newlabel{fig:cells-bad}{{11{\greekscript \textalpha \textnumeralsigngreek }}{12}} +\newlabel{sub@fig:cells-bad}{{{\greekscript \textalpha \textnumeralsigngreek }}{12}} +\newlabel{fig:cells-good}{{11{\greekscript \textbeta \textnumeralsigngreek }}{12}} +\newlabel{sub@fig:cells-good}{{{\greekscript \textbeta \textnumeralsigngreek }}{12}} +\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Η εικόνα των κυττάρων γκρίζα\relax }}{13}{}\protected@file@percent } +\newlabel{fig:cells-gray}{{12}{13}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Πολυκλιμακωτή Ανίχνευση \foreignlanguage {english}{Blobs}}{13}{}\protected@file@percent } +\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Πολυκλιμακωτή ανίχνευση \foreignlanguage {english}{blobs} στην εικόνα \foreignlanguage {english}{Up}\relax }}{14}{}\protected@file@percent } +\newlabel{fig:up-multiscale}{{13}{14}} +\newlabel{fig:cells-multiscale-bad}{{14{\greekscript \textalpha \textnumeralsigngreek }}{15}} +\newlabel{sub@fig:cells-multiscale-bad}{{{\greekscript \textalpha \textnumeralsigngreek }}{15}} +\newlabel{fig:cells-multiscale-good}{{14{\greekscript \textbeta \textnumeralsigngreek }}{15}} +\newlabel{sub@fig:cells-multiscale-good}{{{\greekscript \textbeta \textnumeralsigngreek }}{15}} +\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Πολυκλιμακωτή ανίχνευση \foreignlanguage {english}{blobs} σε κύτταρα\relax }}{15}{}\protected@file@percent } +\newlabel{fig:cells-multiscale-pair}{{14}{15}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Επιτάχυνση Ανίχνευσης \foreignlanguage {english}{Blobs}}{16}{}\protected@file@percent } +\newlabel{fig:up-ii}{{15{\greekscript \textalpha \textnumeralsigngreek }}{17}} +\newlabel{sub@fig:up-ii}{{{\greekscript \textalpha \textnumeralsigngreek }}{17}} +\newlabel{fig:cells-ii}{{15{\greekscript \textbeta \textnumeralsigngreek }}{17}} +\newlabel{sub@fig:cells-ii}{{{\greekscript \textbeta \textnumeralsigngreek }}{17}} +\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Προσέγγιση ανίχνευσης \foreignlanguage {english}{blobs} με ολοκληρωτικές εικόνες\relax }}{17}{}\protected@file@percent } +\newlabel{fig:ii}{{15}{17}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Επιτάχυνση Πολυκλιμακωτής Ανίχνευση \foreignlanguage {english}{Blobs}}{18}{}\protected@file@percent } +\newlabel{fig:cells-multiscale-ii}{{16{\greekscript \textalpha \textnumeralsigngreek }}{18}} +\newlabel{sub@fig:cells-multiscale-ii}{{{\greekscript \textalpha \textnumeralsigngreek }}{18}} +\newlabel{fig:cells-multiscale-ii}{{16{\greekscript \textbeta \textnumeralsigngreek }}{18}} +\newlabel{sub@fig:cells-multiscale-ii}{{{\greekscript \textbeta \textnumeralsigngreek }}{18}} +\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Προσέγγιση πολυκλιμακωτής ανίχνευσης \foreignlanguage {english}{blobs} με ολοκληρωτικές εικόνες\relax }}{18}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {3}Παράρτημα}{19}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Επιτάχυνση χρήσει ολοκληρωτικών εικόνων και \foreignlanguage {english}{box filters}}{19}{}\protected@file@percent } +\newlabel{section:details}{{3.1}{19}} +\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Σύγκριση ταχύτητας διαφόρων υλοποιήσεων υπολογισμού μερικών παραγώγων\relax }}{19}{}\protected@file@percent } +\newlabel{fig:grad-comparison}{{17}{19}} +\gdef \@abspage@last{19} diff --git a/lab1/report/lab1_part12_report.log b/lab1/report/lab1_part12_report.log new file mode 100644 index 0000000..4576c3b --- /dev/null +++ b/lab1/report/lab1_part12_report.log @@ -0,0 +1,868 @@ +This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=pdflatex 2023.3.24) 6 APR 2023 20:50 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**lab1_report_nocode.tex +(./lab1_report_nocode.tex +LaTeX2e <2021-11-15> patch level 1 +L3 programming layer <2022-01-21> +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2021/10/04 v1.4n Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo +File: size10.clo 2021/10/04 v1.4n Standard LaTeX file (size option) +) +\c@part=\count185 +\c@section=\count186 +\c@subsection=\count187 +\c@subsubsection=\count188 +\c@paragraph=\count189 +\c@subparagraph=\count190 +\c@figure=\count191 +\c@table=\count192 +\abovecaptionskip=\skip47 +\belowcaptionskip=\skip48 +\bibindent=\dimen138 +) +(/usr/share/texlive/texmf-dist/tex/generic/babel/babel.sty +Package: babel 2022/01/26 3.70 The Babel package +\babel@savecnt=\count193 +\U@D=\dimen139 +\l@unhyphenated=\language7 + +(/usr/share/texlive/texmf-dist/tex/generic/babel/txtbabel.def) +\bbl@readstream=\read2 +\bbl@dirlevel=\count194 + +(/usr/share/texlive/texmf-dist/tex/generic/babel-english/english.ldf +Language: english 2017/06/06 v3.3r English support from the babel system +Package babel Info: Hyphen rules for 'british' set to \l@english +(babel) (\language0). Reported on input line 82. +Package babel Info: Hyphen rules for 'UKenglish' set to \l@english +(babel) (\language0). Reported on input line 83. +Package babel Info: Hyphen rules for 'canadian' set to \l@english +(babel) (\language0). Reported on input line 102. +Package babel Info: Hyphen rules for 'australian' set to \l@english +(babel) (\language0). Reported on input line 105. +Package babel Info: Hyphen rules for 'newzealand' set to \l@english +(babel) (\language0). Reported on input line 108. +) +(/usr/share/texlive/texmf-dist/tex/generic/babel-greek/greek.ldf +Language: greek 2020/11/10 v1.10 Greek support for the babel system +\bbl@monogreek=\count195 +\bbl@polygreek=\count196 +\bbl@ancientgreek=\count197 + +(/usr/share/texlive/texmf-dist/tex/latex/greek-fontenc/lgrenc.def +File: lgrenc.def 2020/10/13 2.0 LGR Greek font encoding definitions +Now handling font encoding LGR ... +... processing UTF-8 mapping file for font encoding LGR + +(/usr/share/texlive/texmf-dist/tex/latex/greek-inputenc/lgrenc.dfu +File: lgrenc.dfu 2019/07/11 1.7 UTF-8 support for Greek + defining Unicode char U+00A8 (decimal 168) + defining Unicode char U+00AB (decimal 171) + defining Unicode char U+00AF (decimal 175) + defining Unicode char U+00B4 (decimal 180) + defining Unicode char U+00B7 (decimal 183) + defining Unicode char U+00BB (decimal 187) + defining Unicode char U+0259 (decimal 601) + defining Unicode char U+02D8 (decimal 728) + defining Unicode char U+0374 (decimal 884) + defining Unicode char U+0375 (decimal 885) + defining Unicode char U+037A (decimal 890) + defining Unicode char U+037E (decimal 894) + defining Unicode char U+0384 (decimal 900) + defining Unicode char U+0385 (decimal 901) + defining Unicode char U+0386 (decimal 902) + defining Unicode char U+0387 (decimal 903) + defining Unicode char U+0388 (decimal 904) + defining Unicode char U+0389 (decimal 905) + defining Unicode char U+038A (decimal 906) + defining Unicode char U+038C (decimal 908) + defining Unicode char U+038E (decimal 910) + defining Unicode char U+038F (decimal 911) + defining Unicode char U+0390 (decimal 912) + defining Unicode char U+0391 (decimal 913) + defining Unicode char U+0392 (decimal 914) + defining Unicode char U+0393 (decimal 915) + defining Unicode char U+0394 (decimal 916) + defining Unicode char U+0395 (decimal 917) + defining Unicode char U+0396 (decimal 918) + defining Unicode char U+0397 (decimal 919) + defining Unicode char U+0398 (decimal 920) + defining Unicode char U+0399 (decimal 921) + defining Unicode char U+039A (decimal 922) + defining Unicode char U+039B (decimal 923) + defining Unicode char U+039C (decimal 924) + defining Unicode char U+039D (decimal 925) + defining Unicode char U+039E (decimal 926) + defining Unicode char U+039F (decimal 927) + defining Unicode char U+03A0 (decimal 928) + defining Unicode char U+03A1 (decimal 929) + defining Unicode char U+03A3 (decimal 931) + defining Unicode char U+03A4 (decimal 932) + defining Unicode char U+03A5 (decimal 933) + defining Unicode char U+03A6 (decimal 934) + defining Unicode char U+03A7 (decimal 935) + defining Unicode char U+03A8 (decimal 936) + defining Unicode char U+03A9 (decimal 937) + defining Unicode char U+03AA (decimal 938) + defining Unicode char U+03AB (decimal 939) + defining Unicode char U+03AC (decimal 940) + defining Unicode char U+03AD (decimal 941) + defining Unicode char U+03AE (decimal 942) + defining Unicode char U+03AF (decimal 943) + defining Unicode char U+03B0 (decimal 944) + defining Unicode char U+03B1 (decimal 945) + defining Unicode char U+03B2 (decimal 946) + defining Unicode char U+03B3 (decimal 947) + defining Unicode char U+03B4 (decimal 948) + defining Unicode char U+03B5 (decimal 949) + defining Unicode char U+03B6 (decimal 950) + defining Unicode char U+03B7 (decimal 951) + defining Unicode char U+03B8 (decimal 952) + defining Unicode char U+03B9 (decimal 953) + defining Unicode char U+03BA (decimal 954) + defining Unicode char U+03BB (decimal 955) + defining Unicode char U+03BC (decimal 956) + defining Unicode char U+03BD (decimal 957) + defining Unicode char U+03BE (decimal 958) + defining Unicode char U+03BF (decimal 959) + defining Unicode char U+03C0 (decimal 960) + defining Unicode char U+03C1 (decimal 961) + defining Unicode char U+03C2 (decimal 962) + defining Unicode char U+03C3 (decimal 963) + defining Unicode char U+03C4 (decimal 964) + defining Unicode char U+03C5 (decimal 965) + defining Unicode char U+03C6 (decimal 966) + defining Unicode char U+03C7 (decimal 967) + defining Unicode char U+03C8 (decimal 968) + defining Unicode char U+03C9 (decimal 969) + defining Unicode char U+03CA (decimal 970) + defining Unicode char U+03CB (decimal 971) + defining Unicode char U+03CC (decimal 972) + defining Unicode char U+03CD (decimal 973) + defining Unicode char U+03CE (decimal 974) + defining Unicode char U+03D0 (decimal 976) + defining Unicode char U+03D1 (decimal 977) + defining Unicode char U+03D5 (decimal 981) + defining Unicode char U+03D6 (decimal 982) + defining Unicode char U+03D8 (decimal 984) + defining Unicode char U+03D9 (decimal 985) + defining Unicode char U+03DA (decimal 986) + defining Unicode char U+03DB (decimal 987) + defining Unicode char U+03DC (decimal 988) + defining Unicode char U+03DD (decimal 989) + defining Unicode char U+03DF (decimal 991) + defining Unicode char U+03E0 (decimal 992) + defining Unicode char U+03E1 (decimal 993) + defining Unicode char U+03F0 (decimal 1008) + defining Unicode char U+03F1 (decimal 1009) + defining Unicode char U+03F4 (decimal 1012) + defining Unicode char U+03F5 (decimal 1013) + defining Unicode char U+1F00 (decimal 7936) + defining Unicode char U+1F01 (decimal 7937) + defining Unicode char U+1F02 (decimal 7938) + defining Unicode char U+1F03 (decimal 7939) + defining Unicode char U+1F04 (decimal 7940) + defining Unicode char U+1F05 (decimal 7941) + defining Unicode char U+1F06 (decimal 7942) + defining Unicode char U+1F07 (decimal 7943) + defining Unicode char U+1F08 (decimal 7944) + defining Unicode char U+1F09 (decimal 7945) + defining Unicode char U+1F0A (decimal 7946) + defining Unicode char U+1F0B (decimal 7947) + defining Unicode char U+1F0C (decimal 7948) + defining Unicode char U+1F0D (decimal 7949) + defining Unicode char U+1F0E (decimal 7950) + defining Unicode char U+1F0F (decimal 7951) + defining Unicode char U+1F10 (decimal 7952) + defining Unicode char U+1F11 (decimal 7953) + defining Unicode char U+1F12 (decimal 7954) + defining Unicode char U+1F13 (decimal 7955) + defining Unicode char U+1F14 (decimal 7956) + defining Unicode char U+1F15 (decimal 7957) + defining Unicode char U+1F18 (decimal 7960) + defining Unicode char U+1F19 (decimal 7961) + defining Unicode char U+1F1A (decimal 7962) + defining Unicode char U+1F1B (decimal 7963) + defining Unicode char U+1F1C (decimal 7964) + defining Unicode char U+1F1D (decimal 7965) + defining Unicode char U+1F20 (decimal 7968) + defining Unicode char U+1F21 (decimal 7969) + defining Unicode char U+1F22 (decimal 7970) + defining Unicode char U+1F23 (decimal 7971) + defining Unicode char U+1F24 (decimal 7972) + defining Unicode char U+1F25 (decimal 7973) + defining Unicode char U+1F26 (decimal 7974) + defining Unicode char U+1F27 (decimal 7975) + defining Unicode char U+1F28 (decimal 7976) + defining Unicode char U+1F29 (decimal 7977) + defining Unicode char U+1F2A (decimal 7978) + defining Unicode char U+1F2B (decimal 7979) + defining Unicode char U+1F2C (decimal 7980) + defining Unicode char U+1F2D (decimal 7981) + defining Unicode char U+1F2E (decimal 7982) + defining Unicode char U+1F2F (decimal 7983) + defining Unicode char U+1F30 (decimal 7984) + defining Unicode char U+1F31 (decimal 7985) + defining Unicode char U+1F32 (decimal 7986) + defining Unicode char U+1F33 (decimal 7987) + defining Unicode char U+1F34 (decimal 7988) + defining Unicode char U+1F35 (decimal 7989) + defining Unicode char U+1F36 (decimal 7990) + defining Unicode char U+1F37 (decimal 7991) + defining Unicode char U+1F38 (decimal 7992) + defining Unicode char U+1F39 (decimal 7993) + defining Unicode char U+1F3A (decimal 7994) + defining Unicode char U+1F3B (decimal 7995) + defining Unicode char U+1F3C (decimal 7996) + defining Unicode char U+1F3D (decimal 7997) + defining Unicode char U+1F3E (decimal 7998) + defining Unicode char U+1F3F (decimal 7999) + defining Unicode char U+1F40 (decimal 8000) + defining Unicode char U+1F41 (decimal 8001) + defining Unicode char U+1F42 (decimal 8002) + defining Unicode char U+1F43 (decimal 8003) + defining Unicode char U+1F44 (decimal 8004) + defining Unicode char U+1F45 (decimal 8005) + defining Unicode char U+1F48 (decimal 8008) + defining Unicode char U+1F49 (decimal 8009) + defining Unicode char U+1F4A (decimal 8010) + defining Unicode char U+1F4B (decimal 8011) + defining Unicode char U+1F4C (decimal 8012) + defining Unicode char U+1F4D (decimal 8013) + defining Unicode char U+1F50 (decimal 8016) + defining Unicode char U+1F51 (decimal 8017) + defining Unicode char U+1F52 (decimal 8018) + defining Unicode char U+1F53 (decimal 8019) + defining Unicode char U+1F54 (decimal 8020) + defining Unicode char U+1F55 (decimal 8021) + defining Unicode char U+1F56 (decimal 8022) + defining Unicode char U+1F57 (decimal 8023) + defining Unicode char U+1F59 (decimal 8025) + defining Unicode char U+1F5B (decimal 8027) + defining Unicode char U+1F5D (decimal 8029) + defining Unicode char U+1F5F (decimal 8031) + defining Unicode char U+1F60 (decimal 8032) + defining Unicode char U+1F61 (decimal 8033) + defining Unicode char U+1F62 (decimal 8034) + defining Unicode char U+1F63 (decimal 8035) + defining Unicode char U+1F64 (decimal 8036) + defining Unicode char U+1F65 (decimal 8037) + defining Unicode char U+1F66 (decimal 8038) + defining Unicode char U+1F67 (decimal 8039) + defining Unicode char U+1F68 (decimal 8040) + defining Unicode char U+1F69 (decimal 8041) + defining Unicode char U+1F6A (decimal 8042) + defining Unicode char U+1F6B (decimal 8043) + defining Unicode char U+1F6C (decimal 8044) + defining Unicode char U+1F6D (decimal 8045) + defining Unicode char U+1F6E (decimal 8046) + defining Unicode char U+1F6F (decimal 8047) + defining Unicode char U+1F70 (decimal 8048) + defining Unicode char U+1F71 (decimal 8049) + defining Unicode char U+1F72 (decimal 8050) + defining Unicode char U+1F73 (decimal 8051) + defining Unicode char U+1F74 (decimal 8052) + defining Unicode char U+1F75 (decimal 8053) + defining Unicode char U+1F76 (decimal 8054) + defining Unicode char U+1F77 (decimal 8055) + defining Unicode char U+1F78 (decimal 8056) + defining Unicode char U+1F79 (decimal 8057) + defining Unicode char U+1F7A (decimal 8058) + defining Unicode char U+1F7B (decimal 8059) + defining Unicode char U+1F7C (decimal 8060) + defining Unicode char U+1F7D (decimal 8061) + defining Unicode char U+1F80 (decimal 8064) + defining Unicode char U+1F81 (decimal 8065) + defining Unicode char U+1F82 (decimal 8066) + defining Unicode char U+1F83 (decimal 8067) + defining Unicode char U+1F84 (decimal 8068) + defining Unicode char U+1F85 (decimal 8069) + defining Unicode char U+1F86 (decimal 8070) + defining Unicode char U+1F87 (decimal 8071) + defining Unicode char U+1F88 (decimal 8072) + defining Unicode char U+1F89 (decimal 8073) + defining Unicode char U+1F8A (decimal 8074) + defining Unicode char U+1F8B (decimal 8075) + defining Unicode char U+1F8C (decimal 8076) + defining Unicode char U+1F8D (decimal 8077) + defining Unicode char U+1F8E (decimal 8078) + defining Unicode char U+1F8F (decimal 8079) + defining Unicode char U+1F90 (decimal 8080) + defining Unicode char U+1F91 (decimal 8081) + defining Unicode char U+1F92 (decimal 8082) + defining Unicode char U+1F93 (decimal 8083) + defining Unicode char U+1F94 (decimal 8084) + defining Unicode char U+1F95 (decimal 8085) + defining Unicode char U+1F96 (decimal 8086) + defining Unicode char U+1F97 (decimal 8087) + defining Unicode char U+1F98 (decimal 8088) + defining Unicode char U+1F99 (decimal 8089) + defining Unicode char U+1F9A (decimal 8090) + defining Unicode char U+1F9B (decimal 8091) + defining Unicode char U+1F9C (decimal 8092) + defining Unicode char U+1F9D (decimal 8093) + defining Unicode char U+1F9E (decimal 8094) + defining Unicode char U+1F9F (decimal 8095) + defining Unicode char U+1FA0 (decimal 8096) + defining Unicode char U+1FA1 (decimal 8097) + defining Unicode char U+1FA2 (decimal 8098) + defining Unicode char U+1FA3 (decimal 8099) + defining Unicode char U+1FA4 (decimal 8100) + defining Unicode char U+1FA5 (decimal 8101) + defining Unicode char U+1FA6 (decimal 8102) + defining Unicode char U+1FA7 (decimal 8103) + defining Unicode char U+1FA8 (decimal 8104) + defining Unicode char U+1FA9 (decimal 8105) + defining Unicode char U+1FAA (decimal 8106) + defining Unicode char U+1FAB (decimal 8107) + defining Unicode char U+1FAC (decimal 8108) + defining Unicode char U+1FAD (decimal 8109) + defining Unicode char U+1FAE (decimal 8110) + defining Unicode char U+1FAF (decimal 8111) + defining Unicode char U+1FB0 (decimal 8112) + defining Unicode char U+1FB1 (decimal 8113) + defining Unicode char U+1FB2 (decimal 8114) + defining Unicode char U+1FB3 (decimal 8115) + defining Unicode char U+1FB4 (decimal 8116) + defining Unicode char U+1FB6 (decimal 8118) + defining Unicode char U+1FB7 (decimal 8119) + defining Unicode char U+1FB8 (decimal 8120) + defining Unicode char U+1FB9 (decimal 8121) + defining Unicode char U+1FBA (decimal 8122) + defining Unicode char U+1FBB (decimal 8123) + defining Unicode char U+1FBC (decimal 8124) + defining Unicode char U+1FBD (decimal 8125) + defining Unicode char U+1FBE (decimal 8126) + defining Unicode char U+1FBF (decimal 8127) + defining Unicode char U+1FC0 (decimal 8128) + defining Unicode char U+1FC1 (decimal 8129) + defining Unicode char U+1FC2 (decimal 8130) + defining Unicode char U+1FC3 (decimal 8131) + defining Unicode char U+1FC4 (decimal 8132) + defining Unicode char U+1FC6 (decimal 8134) + defining Unicode char U+1FC7 (decimal 8135) + defining Unicode char U+1FC8 (decimal 8136) + defining Unicode char U+1FC9 (decimal 8137) + defining Unicode char U+1FCA (decimal 8138) + defining Unicode char U+1FCB (decimal 8139) + defining Unicode char U+1FCC (decimal 8140) + defining Unicode char U+1FCD (decimal 8141) + defining Unicode char U+1FCE (decimal 8142) + defining Unicode char U+1FCF (decimal 8143) + defining Unicode char U+1FD0 (decimal 8144) + defining Unicode char U+1FD1 (decimal 8145) + defining Unicode char U+1FD2 (decimal 8146) + defining Unicode char U+1FD3 (decimal 8147) + defining Unicode char U+1FD6 (decimal 8150) + defining Unicode char U+1FD7 (decimal 8151) + defining Unicode char U+1FD8 (decimal 8152) + defining Unicode char U+1FD9 (decimal 8153) + defining Unicode char U+1FDA (decimal 8154) + defining Unicode char U+1FDB (decimal 8155) + defining Unicode char U+1FDD (decimal 8157) + defining Unicode char U+1FDE (decimal 8158) + defining Unicode char U+1FDF (decimal 8159) + defining Unicode char U+1FE0 (decimal 8160) + defining Unicode char U+1FE1 (decimal 8161) + defining Unicode char U+1FE2 (decimal 8162) + defining Unicode char U+1FE3 (decimal 8163) + defining Unicode char U+1FE4 (decimal 8164) + defining Unicode char U+1FE5 (decimal 8165) + defining Unicode char U+1FE6 (decimal 8166) + defining Unicode char U+1FE7 (decimal 8167) + defining Unicode char U+1FE8 (decimal 8168) + defining Unicode char U+1FE9 (decimal 8169) + defining Unicode char U+1FEA (decimal 8170) + defining Unicode char U+1FEB (decimal 8171) + defining Unicode char U+1FEC (decimal 8172) + defining Unicode char U+1FED (decimal 8173) + defining Unicode char U+1FEE (decimal 8174) + defining Unicode char U+1FEF (decimal 8175) + defining Unicode char U+1FF2 (decimal 8178) + defining Unicode char U+1FF3 (decimal 8179) + defining Unicode char U+1FF4 (decimal 8180) + defining Unicode char U+1FF6 (decimal 8182) + defining Unicode char U+1FF7 (decimal 8183) + defining Unicode char U+1FF8 (decimal 8184) + defining Unicode char U+1FF9 (decimal 8185) + defining Unicode char U+1FFA (decimal 8186) + defining Unicode char U+1FFB (decimal 8187) + defining Unicode char U+1FFC (decimal 8188) + defining Unicode char U+1FFD (decimal 8189) + defining Unicode char U+1FFE (decimal 8190) + defining Unicode char U+2013 (decimal 8211) + defining Unicode char U+2014 (decimal 8212) + defining Unicode char U+2018 (decimal 8216) + defining Unicode char U+2019 (decimal 8217) + defining Unicode char U+201A (decimal 8218) + defining Unicode char U+2030 (decimal 8240) + defining Unicode char U+2039 (decimal 8249) + defining Unicode char U+203A (decimal 8250) + defining Unicode char U+20AC (decimal 8364) + defining Unicode char U+2126 (decimal 8486) + defining Unicode char U+10144 (decimal 65860) + defining Unicode char U+10145 (decimal 65861) + defining Unicode char U+10146 (decimal 65862) + defining Unicode char U+10147 (decimal 65863) +) +(/usr/share/texlive/texmf-dist/tex/latex/greek-fontenc/greek-fontenc.def +File: greek-fontenc.def 2020/10/30 2.0 Common Greek font encoding definitions +)) +LaTeX Info: Redefining \& on input line 125. +)) +(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +Package: inputenc 2021/02/14 v1.3d Input encoding file +\inpenc@prehook=\toks16 +\inpenc@posthook=\toks17 +) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2021/10/15 v2.17l AMS math features +\@mathmargin=\skip49 + +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2021/08/26 v2.01 AMS text + +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen140 +)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen141 +) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 2021/08/26 v2.02 operator names +) +\inf@bad=\count198 +LaTeX Info: Redefining \frac on input line 234. +\uproot@=\count199 +\leftroot@=\count266 +LaTeX Info: Redefining \overline on input line 399. +\classnum@=\count267 +\DOTSCASE@=\count268 +LaTeX Info: Redefining \ldots on input line 496. +LaTeX Info: Redefining \dots on input line 499. +LaTeX Info: Redefining \cdots on input line 620. +\Mathstrutbox@=\box50 +\strutbox@=\box51 +\big@size=\dimen142 +LaTeX Font Info: Redeclaring font encoding OML on input line 743. +LaTeX Font Info: Redeclaring font encoding OMS on input line 744. +\macc@depth=\count269 +\c@MaxMatrixCols=\count270 +\dotsspace@=\muskip16 +\c@parentequation=\count271 +\dspbrk@lvl=\count272 +\tag@help=\toks19 +\row@=\count273 +\column@=\count274 +\maxfields@=\count275 +\andhelp@=\toks20 +\eqnshift@=\dimen143 +\alignsep@=\dimen144 +\tagshift@=\dimen145 +\tagwidth@=\dimen146 +\totwidth@=\dimen147 +\lineht@=\dimen148 +\@envbody=\toks21 +\multlinegap=\skip50 +\multlinetaggap=\skip51 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2938. +LaTeX Info: Redefining \] on input line 2939. +) +(/usr/share/texlive/texmf-dist/tex/latex/chngcntr/chngcntr.sty +Package: chngcntr 2018/04/09 v1.1a change counter resetting +Package chngcntr Info: \counterwithout already defined. +(chngcntr) Quitting chngcntr on input line 21. +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks23 +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2021/03/04 v1.4d Standard LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2021/08/11 v1.11 sin cos tan (DPC) +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/graphics.cfg +File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration +) +Package graphics Info: Driver file: pdftex.def on input line 107. + +(/usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def +File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex +)) +\Gin@req@height=\dimen149 +\Gin@req@width=\dimen150 +) +(/usr/share/texlive/texmf-dist/tex/latex/caption/subcaption.sty +Package: subcaption 2020/10/07 v1.3j Sub-captions (AR) + +(/usr/share/texlive/texmf-dist/tex/latex/caption/caption.sty +Package: caption 2020/10/26 v3.5g Customizing captions (AR) + +(/usr/share/texlive/texmf-dist/tex/latex/caption/caption3.sty +Package: caption3 2020/10/21 v2.2e caption3 kernel (AR) +\captionmargin=\dimen151 +\captionmargin@=\dimen152 +\captionwidth=\dimen153 +\caption@tempdima=\dimen154 +\caption@indent=\dimen155 +\caption@parindent=\dimen156 +\caption@hangindent=\dimen157 +Package caption Info: Standard document class detected. +) +\c@caption@flags=\count276 +\c@continuedfloat=\count277 +) +\c@subfigure=\count278 +\c@subtable=\count279 +) +(/usr/share/texlive/texmf-dist/tex/latex/placeins/placeins.sty +Package: placeins 2005/04/18 v 2.2 +) +Package babel Info: Making ; an active character on input line 16. + +(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def +File: l3backend-pdftex.def 2022-01-12 L3 backend support: PDF output (pdfTeX) +\l__color_backend_stack_int=\count280 +\l__pdf_internal_box=\box52 +) +(./lab1_report_nocode.aux +LaTeX Font Info: Trying to load font information for LGR+cmr on input line 5 +. + +(/usr/share/texlive/texmf-dist/tex/latex/cbfonts-fd/lgrcmr.fd +File: lgrcmr.fd 2017/07/29 v1.2 Greek European Computer Regular +) + +LaTeX Warning: Label `fig:up' multiply defined. + + +LaTeX Warning: Label `sub@fig:up' multiply defined. + + +LaTeX Warning: Label `fig:cells-multiscale-ii' multiply defined. + + +LaTeX Warning: Label `sub@fig:cells-multiscale-ii' multiply defined. + +) +\openout1 = `lab1_report_nocode.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. +LaTeX Font Info: Checking defaults for LGR/cmr/m/n on input line 29. +LaTeX Font Info: ... okay on input line 29. + (/usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +\scratchcounter=\count281 +\scratchdimen=\dimen158 +\scratchbox=\box53 +\nofMPsegments=\count282 +\nofMParguments=\count283 +\everyMPshowfont=\toks24 +\MPscratchCnt=\count284 +\MPscratchDim=\dimen159 +\MPnumerator=\count285 +\makeMPintoPDFobject=\count286 +\everyMPtoPDFconversion=\toks25 +) (/usr/share/texlive/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty +Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf +Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4 +85. + +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg +File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv +e +)) +Package caption Info: Begin \AtBeginDocument code. +Package caption Info: End \AtBeginDocument code. +LaTeX Font Info: Trying to load font information for LGR+cmtt on input line +30. + +(/usr/share/texlive/texmf-dist/tex/latex/cbfonts-fd/lgrcmtt.fd +File: lgrcmtt.fd 2017/07/29 v1.2 Greek European Computer Typewriter +) [1 + +{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./lab1_report_nocode.toc) +\tf@toc=\write3 +\openout3 = `lab1_report_nocode.toc'. + + [2] +Overfull \hbox (14.14018pt too wide) in paragraph at lines 40--41 +\LGR/cmr/m/n/10 Oi ei-knec ei-sdou dh-miour-go-ntai dia-bzo-ntac thn de-do- +mnh ei-kna ''[]\OT1/cmr/m/n/10 edgetest[]23.png[]\LGR/cmr/m/n/10 `` + [] + +[3] +Overfull \hbox (3.9925pt too wide) in paragraph at lines 96--96 +[]\LGR/cmr/bx/n/12 Axiolghsh twn A-po-te-le-smtwn A-nsqneu-shc Ak- + [] + + +Overfull \hbox (13.00157pt too wide) in paragraph at lines 116--117 +\LGR/cmr/m/n/10 Paratjentai ta a-po-te-lsma-ta e-far-mo-gc thc me-jdou sthn + ei-knac []\OT1/cmr/m/n/10 ed-getest[]23.png[]\LGR/cmr/m/n/10 . + [] + +<../image-plots/edgetest_23.png, id=27, 513.92pt x 513.92pt> +File: ../image-plots/edgetest_23.png Graphic file (type png) + +Package pdftex.def Info: ../image-plots/edgetest_23.png used on input line 120 +. +(pdftex.def) Requested size: 172.5pt x 172.50342pt. + +LaTeX Warning: `h' float specifier changed to `ht'. + +<../image-plots/edges-intro0.jpg, id=28, 462.528pt x 346.896pt> +File: ../image-plots/edges-intro0.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/edges-intro0.jpg used on input line 12 +6. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + +LaTeX Warning: `!h' float specifier changed to `!ht'. + +[4] [5 <../image-plots/edgetest_23.png> <../image-plots/edges-intro0.jpg>] +File: ../image-plots/edges-intro0.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/edges-intro0.jpg used on input line 14 +4. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. +<../image-plots/kyoto_edges.jpg, id=36, 803.0pt x 536.0025pt> +File: ../image-plots/kyoto_edges.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/kyoto_edges.jpg used on input line 176 +. +(pdftex.def) Requested size: 172.5pt x 115.14014pt. + +[6] +<../image-plots/edges-real.jpg, id=41, 462.528pt x 346.896pt> +File: ../image-plots/edges-real.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/edges-real.jpg used on input line 182. + +(pdftex.def) Requested size: 310.4979pt x 232.8849pt. + [7 <../image-plots/kyoto_edges.jpg> <../image-plots/edges-real.jpg>] +<../image-plots/corner-detection-eigenvalues-scaled.jpg, id=46, 583.17876pt x 2 +33.87375pt> +File: ../image-plots/corner-detection-eigenvalues-scaled.jpg Graphic file (type + jpg) + +Package pdftex.def Info: ../image-plots/corner-detection-eigenvalues-scaled.jpg + used on input line 230. +(pdftex.def) Requested size: 345.0pt x 138.35901pt. + +[8 <../image-plots/corner-detection-eigenvalues-scaled.jpg>] +<../image-plots/corner-detection.jpg, id=51, 462.528pt x 346.896pt> +File: ../image-plots/corner-detection.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/corner-detection.jpg used on input lin +e 257. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + [9 <../image-plots/corner-detection.jpg>] +<../image-plots/corner-detection-multiscale.jpg, id=55, 462.528pt x 346.896pt> +File: ../image-plots/corner-detection-multiscale.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/corner-detection-multiscale.jpg used o +n input line 286. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + [10 <../image-plots/corner-detection-multiscale.jpg>] +<../image-plots/up.png, id=59, 999.735pt x 563.10374pt> +File: ../image-plots/up.png Graphic file (type png) + +Package pdftex.def Info: ../image-plots/up.png used on input line 320. +(pdftex.def) Requested size: 172.5pt x 97.16127pt. +<../image-plots/cells.jpg, id=61, 242.9075pt x 208.78pt> +File: ../image-plots/cells.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/cells.jpg used on input line 326. +(pdftex.def) Requested size: 138.00052pt x 118.6108pt. + +Overfull \hbox (2.22168pt too wide) in paragraph at lines 318--330 +[]$[]$ $[]$ + [] + +[11 <../image-plots/up.png> <../image-plots/cells.jpg>] +<../image-plots/blob-detection-up-scaled.jpg, id=69, 545.03625pt x 303.1325pt> +File: ../image-plots/blob-detection-up-scaled.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-up-scaled.jpg used on i +nput line 338. +(pdftex.def) Requested size: 345.0pt x 191.87643pt. +<../image-plots/blob-detection-cells-bad-scaled.jpg, id=70, 515.9275pt x 412.54 +124pt> +File: ../image-plots/blob-detection-cells-bad-scaled.jpg Graphic file (type jpg +) + +Package pdftex.def Info: ../image-plots/blob-detection-cells-bad-scaled.jpg us +ed on input line 354. +(pdftex.def) Requested size: 169.0519pt x 135.17592pt. +<../image-plots/blob-detection-cells-good-scaled.jpg, id=71, 514.92375pt x 411. +5375pt> +File: ../image-plots/blob-detection-cells-good-scaled.jpg Graphic file (type jp +g) + +Package pdftex.def Info: ../image-plots/blob-detection-cells-good-scaled.jpg u +sed on input line 360. +(pdftex.def) Requested size: 169.0519pt x 135.10448pt. + [12 <../image-plots/blob-detection-up-scaled.jpg> <../image-plots/blob-detecti +on-cells-bad-scaled.jpg> <../image-plots/blob-detection-cells-good-scaled.jpg>] +<../image-plots/cells-gray-scaled.jpg, id=75, 500.87125pt x 400.49625pt> +File: ../image-plots/cells-gray-scaled.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/cells-gray-scaled.jpg used on input li +ne 371. +(pdftex.def) Requested size: 276.00105pt x 220.70139pt. +<../image-plots/blob-detection-multiscale-up.jpg, id=76, 462.528pt x 346.896pt> + +File: ../image-plots/blob-detection-multiscale-up.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-up.jpg used +on input line 386. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[13 <../image-plots/cells-gray-scaled.jpg>] +<../image-plots/blob-detection-multiscale-cells-bad.jpg, id=81, 462.528pt x 346 +.896pt> +File: ../image-plots/blob-detection-multiscale-cells-bad.jpg Graphic file (type + jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-cells-bad.jpg + used on input line 400. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. +<../image-plots/blob-detection-multiscale-cells-good.jpg, id=82, 462.528pt x 34 +6.896pt> +File: ../image-plots/blob-detection-multiscale-cells-good.jpg Graphic file (typ +e jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-cells-good.jp +g used on input line 406. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + + +LaTeX Warning: Float too large for page by 24.5267pt on input line 412. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[14 <../image-plots/blob-detection-multiscale-up.jpg>] [15 <../image-plots/blob +-detection-multiscale-cells-bad.jpg> <../image-plots/blob-detection-multiscale- +cells-good.jpg>] +<../image-plots/blob-detection-ii-up.jpg, id=89, 462.528pt x 346.896pt> +File: ../image-plots/blob-detection-ii-up.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-ii-up.jpg used on input + line 430. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. +<../image-plots/blob-detection-ii-cells.jpg, id=90, 462.528pt x 346.896pt> +File: ../image-plots/blob-detection-ii-cells.jpg Graphic file (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-ii-cells.jpg used on in +put line 435. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + + +LaTeX Warning: Float too large for page by 24.5267pt on input line 441. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[16 + +] [17 <../image-plots/blob-detection-ii-up.jpg> <../image-plots/blob-detection- +ii-cells.jpg>] +<../image-plots/blob-detection-multiscale-ii-up-scaled.jpg, id=101, 543.02875pt + x 311.1625pt> +File: ../image-plots/blob-detection-multiscale-ii-up-scaled.jpg Graphic file (t +ype jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-ii-up-scaled. +jpg used on input line 451. +(pdftex.def) Requested size: 241.49895pt x 138.38379pt. +<../image-plots/blob-detection-multiscale-ii-cells-scaled.jpg, id=102, 490.8337 +6pt x 414.54875pt> +File: ../image-plots/blob-detection-multiscale-ii-cells-scaled.jpg Graphic file + (type jpg) + +Package pdftex.def Info: ../image-plots/blob-detection-multiscale-ii-cells-scal +ed.jpg used on input line 456. +(pdftex.def) Requested size: 241.49895pt x 203.96562pt. + [18 + + <../image-plots/blob-detection-multiscale-ii-up-scaled.jpg> <../image-plots/bl +ob-detection-multiscale-ii-cells-scaled.jpg>] +<../image-plots/grad-comparison.png, id=106, 462.528pt x 346.896pt> +File: ../image-plots/grad-comparison.png Graphic file (type png) + +Package pdftex.def Info: ../image-plots/grad-comparison.png used on input line + 474. +(pdftex.def) Requested size: 345.0pt x 258.76335pt. + [19 <../image-plots/grad-comparison.png>] (./lab1_report_nocode.aux) + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 5779 strings out of 480171 + 101842 string characters out of 5894489 + 391367 words of memory out of 5000000 + 23659 multiletter control sequences out of 15000+600000 + 482162 words of font info for 57 fonts, out of 8000000 for 9000 + 59 hyphenation exceptions out of 8191 + 67i,11n,77p,2142b,560s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on lab1_report_nocode.pdf (19 pages, 2233397 bytes). +PDF statistics: + 212 PDF objects out of 1000 (max. 8388607) + 117 compressed objects within 2 object streams + 0 named destinations out of 1000 (max. 500000) + 106 words of extra memory for PDF output out of 10000 (max. 10000000) + diff --git a/lab1/report/lab1_part12_report.pdf b/lab1/report/lab1_part12_report.pdf new file mode 100644 index 0000000..03b06a9 Binary files /dev/null and b/lab1/report/lab1_part12_report.pdf differ diff --git a/lab1/report/lab1_part12_report.tex b/lab1/report/lab1_part12_report.tex new file mode 100644 index 0000000..7806abc --- /dev/null +++ b/lab1/report/lab1_part12_report.tex @@ -0,0 +1,482 @@ +\documentclass{article} +\usepackage[english,greek, main=greek]{babel} +\usepackage[utf8]{inputenc} + +\usepackage{amsmath} +\usepackage{chngcntr} +\counterwithin{equation}{section} + +\usepackage{graphicx} +\usepackage{subcaption} +\usepackage{placeins} + +\newcommand{\eng}[1]{\foreignlanguage{english}{#1}} +\newcommand{\Alpha}{\mathrm{A}} + +\useshorthands{;} +\defineshorthand{;}{?} + +\title{Όραση Υπολογιστών\\ + \large Εργαστήριο 1} +\author{Αναστάσιος Στέφανος Αναγνώστου\\ + \texttt{03119051} + \and + Σπυρίδων Παπαδόπουλος\\ + \texttt{03119058}} + +\date{7 Απριλίου 2023} + +\begin{document} +\maketitle + +\newpage +\tableofcontents +\newpage + +\section{Μέρος 1ο} + +\subsection{Δημιουργία Εικόνων Εισόδου} + +Οι εικόνες εισόδου δημιουργούνται διαβάζοντας την δεδομένη εικόνα ''\eng{edgetest\_23.png}`` και προσθέτοντας θόρυβο σε αυτήν. Προστίθεται αντιστοίχως θόρυβος με \eng{PSNR} 20\eng{dB} και θόρυβος με \eng{PSNR} 10\eng{dB}. Αξιοσημειώτο είναι, ότι ο πρώτος θόρυβος είναι στην πραγματικότητα λιγότερος από τον δεύτερον. Το \eng{PSNR} ορίζεται ως εξής: + +\begin{equation} + \begin{gathered} + PSNR = 20\log_{10} \left(\frac{I_{max}-I_{min}}{\sigma_n} \right)(dB),\\ + I_{max} = \underset{x,y} {\max} I(x,y), I_{min} = \underset{x,y} {\min} I(x,y) + \end{gathered} +\end{equation} + +Φαίνεται ότι από τον ορισμό μπορεί να ληφθεί η μεταβλητότητα του θορύβου, βάσει της οποίας τελικά αυτός ορίζεται. Από την έκφραση της μεταβλητότας, μάλιστα, φαίνεται ότι, όσο μεγαλύτερο το \eng{PSNR} σε \eng{dB} τόσο μικρότερη είναι τελικά η μεταβλητότητα του θορύβου, πράγμα που επαληθεύει τα προαναφερθέντα. + +\begin{equation} + \sigma_n = \frac{\left(I_{max}-I_{min}\right)}{10^{\frac{PSNR}{20}}} +\end{equation} + +\subsection{Υλοποίηση Αλγορίθμων Ανίχνευσης Ακμών} + +Η συνάρτηση που θα αναπτυχθεί εφαρμόζει είτε γραμμική είτε μη γραμμική μέθοδο ανίχνευσης ακμών. + +\subsubsection{Γραμμική Μέθοδος} + +Η μεν γραμμική μέθοδος επιχειρεί την προσέγγιση της λαπλασιανής της εξομαλυμένης εικόνας χρήσει γραμμικών φίλτρων. Συγκεκριμένα, σύμφωνα με την γραμμική μέθοδο: + +\begin{equation} + L = \nabla^2 \left(G_{\sigma} * I\right) = \left( \nabla^2 G_{\sigma} \right) * I +\end{equation} + +\subsubsection{Μη Γραμμική Μέθοδος} + +Η δε μη γραμμική μέθοδος επιχειρεί την προσέγγιση της λαπλασιανής της εξομαλυμένης εικόνας χρήσει μορφολογικών τελεστών. Συγκεκριμένα, σύμφωνα με την μη γραμμική μέθοδο: + +\begin{equation} + \begin{gathered} + I_{\sigma} = G_{\sigma} * I, \\ + L = I_{\sigma} \oplus B + I_{\sigma} \ominus B - 2I_{\sigma} + \end{gathered} +\end{equation} + +Αμφότερες οι μέθοδοι, στην συνέχεια, προσεγγίζουν τα σημεία μηδενισμού της λαπλασιανής. Το κάνουν αυτό δημιουργόντας από την λαπλασιανή μία δυαδική εικόνα και βρίσκοντας στην συνέχεια το περίγραμμά της. Τα σημεία μηδενισμού είναι τα σημεία στα οποία το περίγραμμα έχει μοναδιαία τιμή. + +\begin{equation} + \begin{gathered} + X = (L >= 0)\\ + Y = (X \oplus B) - (X \ominus B)\\ + (i, j) = \arg \left| Y = 1 \right| + \end{gathered} +\end{equation} + +Επειδή, όμως, το κριτήριο αυτό επιστρέφει και σημεία τα οποία δεν ανήκουν σε πραγματικές ακμές, τελικά επιλέγονται τα σημεία αυτά στα οποία η εξομαλυμένη εικόνα παρουσιάζει μεγάλη κλίση: + +\begin{equation} + Y[i, j] = 1 \wedge \lVert \nabla I_{\sigma}[i,j] \rVert > \theta_{edge} \cdot \underset{x, y} \max \lVert \nabla I_{\sigma} \rVert +\end{equation} + +Η ποιότητα της ανίχνευσης ακμών εξαρτάται από την επιλογή των παραμέτρων $\sigma, \theta_{edge}$, δηλαδή αντιστοίχως της παραμέτρου εξομάλυνσης και του κατωφλιού για την αποδοχή μίας ακμής. + +\subsection{Αξιολόγηση των Αποτελεσμάτων Ανίσχνευσης Ακμών} + +Για να αξιολόγηση των αποτελεσμάτων της συνάρτησης, πρέπει να οριστεί ένα ποιοτικό κριτήριο. Εν προκειμένω ορίζεται ο μέσος όρος μεταξύ των αληθώς ανισχνευθεισών ακμών και των ψευδών ανιχνευθεισών ακμών. Φυσικά, είναι αναγκαία η πληροφορία των αληθινών ακμών. Αυτές βρίσκονται από την αυθεντική, μη θορυβημένη εικόνα, χρήσει ενώ κατωφλιού ως εξής: + +\begin{equation} + M = (I \oplus B) - (I \ominus B) \Rightarrow \\ + T = (M > \theta_{real}) +\end{equation} + +Δεδομένων, λοιπόν, των αληθινών ακμών, το ποιοτικό κριτήριο διατυπώνεται ως: + +\begin{equation} + \begin{gathered} + C = \frac{Pr(D|T) + PR(T|D)}{2}, \\ + Pr(T|D) = \frac{\lVert D \cap T \rVert}{\lVert T \rVert} + \end{gathered} +\end{equation} + +\subsection{Αποτελέσματα Εφαρμογής της Συνάρτησης} + +Παρατίθενται τα αποτελέσματα εφαρμογής της μεθόδου στην εικόνας \eng{edgetest\_23.png}. + +\begin{figure}[h] + \centering + \includegraphics[width=0.5\textwidth]{../image-plots/edgetest_23.png} + \caption{Η δεδομένη εικόνα εισόδου} + \label{fig:edge-test} +\end{figure} + +\begin{figure}[h!] + \includegraphics[width=\textwidth]{../image-plots/edges-intro0.jpg} + \caption{Θόρυβος \eng{PSNR} 10\eng{dB}} + \label{fig:noise 10db} +\end{figure} +\FloatBarrier + +Όταν η εικόνα \ref{fig:edge-test} θορυβήθηκε με θόρυβο 10 \eng{dB PSNR}, τα αποτελέσματα ήταν αυτά που φαίνονται στην \ref{fig:noise 10db} και οι βαθμολογίες στο κριτήριο ποιότητας οι ακόλουθες: + +\begin{equation} + \begin{gathered} + C_{10db-lin} = 0.6182010279466628\\ + C_{10db-non} = 0.7362110886293316\\ + \end{gathered} +\end{equation} + +Ενώ όταν η εικόνα θορυβήθηκε με θόρυβο 20 \eng{dB PSNR}, τα αποτελέσματα ήταν: + +\begin{figure}[h] + \includegraphics[width=\textwidth]{../image-plots/edges-intro0.jpg} + \caption{Θόρυβος \eng{PSNR} 20\eng{dB}} +\end{figure} +\FloatBarrier + +Με κριτήριο ποιότητας: + +\begin{equation} + \begin{gathered} + C_{20db-lin} = 0.9375887192342924\\ + C_{20db-non} = 0.9671201094187654\\ + \end{gathered} +\end{equation} + +Τα αποτελέσματα επιτεύχθηκαν με τις ακόλουθες παράμετρους: + +\begin{equation} + \begin{gathered} + \sigma = \begin{bmatrix}3 & 1.5 \end{bmatrix}, + \theta = \begin{bmatrix}0.2 & 0.2 \end{bmatrix}, + \theta_{real} = 0,08\\ + \end{gathered} +\end{equation} + +Παρατηρείται ότι η επίδραση του θορύβου είναι καθοριστική, καθώς στην εικόνα με τον λίγοτερο θόρυβο επιτυγχάνεται καλύτερη βαθμολογία στο ποιοτικό κριτήριο. Επίσης, φαίνεται ότι η μη γραμμική μέθοδος πετυχαίνει καλύτερα αποτελέσματα σε κάθε περίπτωση. + +\subsection{Εφαρμογή των Αλγορίθμων Ανίχνευσης Ακμών σε Πραγματικές Εικόνες} + +Η ίδια συνάρτηση χρησιμοποιήθηκε και για την ανίχνευση ακμών στην πραγματική εικόνα του \eng{Kyoto}, όπως φαίνεται στην εικόνα \ref{fig:kyoto}. + +\begin{figure}[h] + \centering + \includegraphics[width=0.5\textwidth]{../image-plots/kyoto_edges.jpg} + \caption{Η πραγματική φωτογραφιά του \eng{Kyoto}} + \label{fig:kyoto} +\end{figure} +\begin{figure}[h] + \centering + \includegraphics[width=0.9\textwidth]{../image-plots/edges-real.jpg} + \caption{Ανίχνευση ακμών στην πραγματική φωτογραφιά του \eng{Kyoto}} + \label{fig:kyoto-edges} +\end{figure} +\FloatBarrier + +Η επεξεργασία έγινε με τις παραμέτρους: + +\begin{equation} + \begin{gathered} + \sigma = 0.3, \theta = 0.2, \theta_{real} = 0.23 \\ + \end{gathered} +\end{equation} + +και πέτυχε τις βαθμολογίες: + +\begin{equation} + \begin{gathered} + C_{lin} = 0.818604135617401\\ + C_{non} = 0.8188562865181751 + \end{gathered} +\end{equation} + +Τα δε οπτικά αποτελέσματα φαίνονται στην εικόνα \ref{fig:kyoto-edges}. Τόσο από την βαθμολογία στο ποιοτικό κριτήριο όσο και οπτικά, φαίνεται ότι αμφότερες η γραμμική και η μη γραμμική μέθοδος έδωσαν πολύ καλά αποτελέσματα. + +\section{Μέρος 2ο} + +Στο σημείο αυτό της εργασίας θα επιχειρηθεί η ανίχνευση διαφόρων χαρακτηριστικών, τόσο σε μία μόνο κλίμακα όσο και σε πολλαπλές κλίμακες. + +\subsection{Ανίχνευση Γωνιών} + +Πρώτα επιχειρείται ανίχνευση γωνιών. Θα παρουσιαστεί η μεθοδολογία και ταυτοχρόνως τα βήματα της επεξεργασίας, για να γίνει σαφής. + +Αρχικά υπολογίζεται ο δομικός τανυστής \eng{\textbf{J}} και οι ιδιοτιμές του. + +\begin{equation} + \begin{gathered} + J_1(x, y) = G_{\rho} * \left(\frac{\partial I_\sigma}{\partial x} \cdot \frac{\partial I_\sigma}{\partial x} \right)(x, y)\\ + J_2(x, y) = G_{\rho} * \left( \frac{\partial I_\sigma}{\partial x} \cdot \frac{\partial I_\sigma}{\partial y} \right)(x, y)\\ + J_3(x, y) = G_{\rho} * \left( \frac{\partial I_\sigma}{\partial y} \cdot \frac{\partial I_\sigma}{\partial y} \right)(x, y)\\ + \lambda_{\pm}(x, y) = \frac{1}{2} \left(J_1 + J_2 \pm \sqrt{\left (J_1 - J_3\right)^2 + 4J_2^2} \right) + \end{gathered} +\end{equation} + +Οι ιδιοτιμές περιέχουν χρήσιμη πληροφορία σχετικά με τις ακμές και τις γωνίες της εικόνας. Παρακάτω, στην εικόνα \ref{fig:kyoto-eigenvalues}, δίνεται η απεικόνισή τους ως γκρίζες εικόνες. + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/corner-detection-eigenvalues-scaled.jpg} + \caption{Απεικόνιση των ιδιοτιμών της εικόνας ως γκρίζες εικόνες} + \label{fig:kyoto-eigenvalues} +\end{figure} +\FloatBarrier + +Φαίνεται ότι η εικόνα η αντιστοιχούσα στην ιδιοτιμή ''-`` αποτυπώνει έντονα τις απολήξεις του πύργου, δηλαδή τις αιχμηρές γωνίες, ενώ η εικόνα αντιστοιχούσα στην ιδιοτιμή ``+'' αποτυπώνει έντονα τα περιγράμματα, δηλαδή τις ακμές. + +Στην συνέχεια, εξάγεται ένα κριτήριο γωνιότητας συναρτήσει των ιδιοτιμών και μίας σταθεράς $k$: + +\begin{equation} + R(x, y) = \lambda_{-}\lambda_{+} - k\cdot\left(\lambda_{-} + \lambda_{+}\right)^2 +\end{equation} + +Τέλος, επιλέγονται ως γωνίες τα σημεία αυτά τα οποία μεγιστοποιούν το κριτήριο εντός τετραγωνικών παραθύρων και αποδίδουν στο κριτήριο γωνιότητας τιμή μεγαλύτερη από ένα κατώφλι. + +\begin{equation} + \begin{gathered} + R(x, y) > \theta_{corn} \cdot R_{max} + \end{gathered} +\end{equation} + +Το αποτέλεσμα εφαρμογής αυτών των συνθηκών στην εικόνα-κριτήριο $R$, για τις παραμέτρους $\sigma = 2, \rho = 2.5, k = 0.05, \theta_{corn} = 0.1$ είναι το ακόλουθο: + + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/corner-detection.jpg} + \caption{Ανίχνευση γωνιών στην εικόνα \eng{Kyoto}} + \label{fig:kyoto-corners} +\end{figure} +\FloatBarrier + +Φαίνεται ότι έχουν εντοπιστεί με επιτυχία πολλές γωνίες, ειδικά οι αιχμηρές απολίξεις του πύργου αλλά και οι ορθές γωνίες οι σχηματιζόμενες από τους πασάλους των κτιρίτων. Ωστόσο, έχουν αναγνωριστει ως γωνίες και ανεπιθύμητα σημεία, όπως τα κλαδιά του δέντρου. Επομένως, συμπεραίνεται ότι η μέθοδος είναι αποτελεσματική αλλά έχει περιθώριο βελτίωσης. + +\subsection{Πολυκλιμακωτή Ανίχνευση Γωνιών} + +Ένα σημαντικό μειονέκτημα της προηγούμενης μεθόδου ήταν ότι περιοριζόταν σε μία μόνο κλίμακα, αφού δεχόταν μόνο ένα ζευγάρι παραμέτρων $(\sigma, \rho)$. Η ιδέα είναι να εφαρμοσθεί η ίδια μέθοδος Ν φορές, κλιμακώνοντας γεωμετρικά κάθε φορά τις παραμέτρους με μία παραμέτρο κλίμακας $s$. Δηλαδή, η επεξεργασία θα γίνεται με τις παραμέτρους: + + \begin{equation} + \begin{gathered} + \sigma_0, \sigma_1, ..., \sigma_{N-1} = s^{0}\sigma_0, s^{1}\sigma_0, ..., \sigma^{N-1}\sigma_0 \\ + \rho_0, \rho_1, ..., \rho_{N-1} = s^{0}\rho_0, s^{1}\rho_0, ..., \rho^{N-1}\rho_0 + \end{gathered} +\end{equation} + +Λόγω των πολλαπλών κλιμάκων, θα επιλεχθούν πολλά σημεία τα οποία έχουν την ίδια πιθανότητα σφάλματος όπως προηγουμένως. Για αυτόν τον λόγο, επιλέγονται τελικά αυτά τα σημεία-γωνίες τα οποία μεγιστοποιούν κάποιο κριτήριο σε μία περιοχή κλιμάκων. Εν προκειμένω, το κριτήριο επιλέγεται να είναι η κανονικοποιημένη Λαπλασιανή της Γκαουσιανής. + +\begin{equation} + \left| LoG(x, y, \sigma_i) \right| = \sigma_i^2 \left|L_xx(x,y, \sigma_i) + L_yy(x, y, \sigma_i) \right| +\end{equation} + +Ουσιαστικά, το σκεπτικό είναι ότι μία γωνία οφείλει να εντοπίζεται τουλάχιστον σε μία μικρή περιοχή κλιμάκων, όχι μόνο σε μία διακεκριμένη κλίμακα. Το αποτέλεσμα της πολυκλιμακωτής μεθόδου στην ίδια εικόνα φαίνεται παρακάτω: + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/corner-detection-multiscale.jpg} + \caption{Πολυκλιμακωτή ανίχνευση γωνιών στην εικόνα \eng{Kyoto}} + \label{fig:kyoto-corners-multiscale} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι εντοπίζονται λιγότερες γωνίες απ'ό,τι προηγουμένως. Επιθεωρώντας την εικόνα, παρατηρείται ότι έπαψαν να εντοπίζονται κάποιες ψεύτικες γωνίες, κυρίως αυτές στα ψιλά κλαδιά του δέντρου, παρασέρνοντας όμως και λίγες πραγματικές, όπως αυτές στον πύργο. Ωστόσο, εξακολουθούν να εντοπίζονται εν πολλοίς οι πραγματικές γωνίες, και μάλιστα με μεγαλύτερη βεβαιότητα, αφού περικλείονται από κύκλους διαφόρων κλιμάκων. Συμπερασματικά, η μέθοδος αυτή είναι σαφώς βελτίωση της προηγούμενης, με αντίτιμο μεγαλύτερη υπολογιστική πολυπλοκότητα. + +\subsection{Ανίχνευση \eng{Blobs}} + +Η ανίχνευση \eng{blobs} αναφέρεται γενικώς στην ανίχνευση περιοχών με κάποια ομοιογένεια. Οι περιοχές αυτές βρίσκονται χρήσει των μερικών παραγώγων δευτέρας τάξεως της εξομαλυμένης εικόνας. Συγκεκριμένα, δεδομένου του Χεσιανού πίνακα: + +\begin{equation} + H(x, y) = \begin{bmatrix} L_{xx}(x, y, \sigma) & L_{xy}(x, y, \sigma) \\ + L_{xy}(x, y, \sigma) & L_{yy}(x, y, \sigma)\end{bmatrix} +\end{equation} + +Το κριτήριο για τον εντοπισμό περιοχών ομοιογένειας είναι απλώς ο μηδενισμός της ορίζουσας: + +\begin{equation} + \begin{gathered} + R(x, y) = \det\left| H(x, y) \right|\\ + (x, y) = \underset{x, y} {\arg} \left( R(x, y) = 0 \right) + \end{gathered} +\end{equation} + +Επομένως, αναπτύσσεται μεθοδολογία πλήρως ανάλογη με την μεθοδολογία για την ανίχνευση ακμών. Δηλαδή, εξομαλύνεται η εικόνα, υπολογίζεται ο Χεσιανός πίνακας και το κριτήριο $R(x, y)$, εντοπίζονται τα σημεία μηδενισμού και επιλέγονται αυτά τα οποία έχουν τιμή στην εικόνα μεγαλύτερη από κάποιο κατώφλι. + +Η μέδοδος εφαρμόζεται στην εικόνα \eng{Up}, από την ομώνυμη ταινία της \eng{Pixar}, και σε μία εικόνα ανθρωπίνων κυττάρων. Πρώτη θα εξεταστεί η εφαρμογή στην εικόνα \eng{Up}. + + +\begin{figure}[h] + \begin{subfigure}{.5\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/up.png} + \caption{Η εικόνα \eng{Up}} + \label{fig:up} + \end{subfigure} + \begin{subfigure}{.5\textwidth} + \centering + \includegraphics[width=0.8\textwidth]{../image-plots/cells.jpg} + \caption{Η εικόνα ανθρωπίνων κυττάρων} + \label{fig:up} + \end{subfigure} + \caption{Οι αρχικές εικόνες για την ανίχνευση \eng{blobs}} +\end{figure} +\FloatBarrier + +Παρακάτω, στην εικόνα \ref{fig:up-blobs} φαίνονται τα αποτελέσματα για παραμέτρους $\sigma = 2.5, \theta = 0.005$ + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-up-scaled.jpg} + \caption{Aνίχνευση \eng{blobs} στην εικόνα \eng{Up}} + \label{fig:up-blobs} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι αν και το κατώφλι για την αποδοχή της περιοχής ομοιογένειας είναι πολύ χαμηλό, τα αποτελέσματα είναι πολύ ικανοποιητικά. Συγκεκριμένα, εντοπίζονται οι περιοχές στα μπαλόνια οι οποίες αντανακλούν το φως του ηλίου και έχουν χαρακτηριστική λευκή λάμψη. Επιπλέον, εντοπίζονται οι περιοχές μεταξύ των μπαλονιών στις οποίες υπάρχει σκοτάδι + +Εξετάζεται τώρα η εφαρμογή της μεθόδου στην εικόνα των κυττάρων. + +Τα αποτελέσματα για τις ίδιες παραμέτρους με πριν είναι αυτά που φαίνονται στην εικόνα \ref{fig:cells-bad} + +\begin{figure}[h] + \centering + \begin{subfigure}{.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-cells-bad-scaled.jpg} + \caption{Aνίχνευση \eng{blobs} στην εικόνα ανθρωπίνων κυττάρων χαμηλό κατώφλι} + \label{fig:cells-bad} + \end{subfigure} + \begin{subfigure}{.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-cells-good-scaled.jpg} + \caption{Aνίχνευση \eng{blobs} στην εικόνα ανθρωπίνων κυττάρων υψηλό κατώφλι} + \label{fig:cells-good} + \end{subfigure} +\end{figure} +\FloatBarrier + +Παρατηρείται, ότι αν και ανιχνεύονται επιτυχώς μερικές από τις λευκές περιοχές ομοιογένειας, ανιχνεύονται επίσης ανεπιθυμητές περιοχές. Αυτό συμβαίνει, γιατί το περιβάλλον της εικόνας είναι τραχύ, με αποτέλεσμα οποιαδήποτε ομοιογένεια να ξεχωρίζει. Αντιθέτως, ο ουρανός προηγουμένως είναι πολύ ομαλός και ομοιογενής, επομένως δεν ξεχωρίζει. Για αυτόν τον λόγο, προσαρμόζεται η παράμετρος $\theta \leftarrow 0.25$. Τα νέα αποτελέσματα φαίνονται στην εικόνα \ref{fig:cells-good}, όπου πλέον ανιχνεύονται σαφώς λίγοτερες περιοχές ομοιογένειες, αλλά ορθότερες. + +\begin{figure}[h] + \centering + \includegraphics[width=0.8\textwidth]{../image-plots/cells-gray-scaled.jpg} + \caption{Η εικόνα των κυττάρων γκρίζα} + \label{fig:cells-gray} +\end{figure} +\FloatBarrier + +Αξιοσημειώτο είναι το γεγονός ότι οι ερυθρές περιοχές γενικώς δεν ανιχνεύονται, σίγουρα όχι στον ίδιο βαθμό με τις λευκές. Αυτό συμβαίνει γιατί η επεξεργασία γίνεται στην γκρίζα μορφή της εικόνας, επομένως η χρωματική διαφορά απαλείφεται, όπως φαίνεται στην εικόνα \ref{fig:cells-gray}. Εφόσον η υφή είναι η ίδια, ανεξαρτήτως χρώματος, γίνεται σαφές ότι δεν μπορούν να διακριθούν στον ίδιο βαθμό με τις λευκές. Εκτός από αυτό, συμπεραίνεται ότι σε τραχύ περιβάλλον πρέπει να αυξηθεί το κατώφλι αποδοχής σημείων. + +\subsection{Πολυκλιμακωτή Ανίχνευση \eng{Blobs}} + +Για την βελτίωση της μεθόδου χρησιμοποιούνται τώρα πολλαπλές κλίμακες, σε πλήρη αναλογία με την πολυκλιμακωτή ανίχνευση γωνιών. + +Στην εικόνα \ref{fig:up-multiscale} φαίνονται τα αποτελέσματα στην εικόνα \eng{Up} για τις τιμές παραμέτρων $\sigma = 3, \theta = 0.05, s = 1.1, N = 8$. Παρατηρείται ότι εντοπίζονται \eng{blobs} ποικίλλων μεγεθών, στα οποία περιλαμβάνονται τόσο ολόκληρα μπαλόνια όσο και απλές αντανακλάσεις φωτός, όπως προηγουμένως. +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-up.jpg} + \caption{Πολυκλιμακωτή ανίχνευση \eng{blobs} στην εικόνα \eng{Up}} + \label{fig:up-multiscale} +\end{figure} +\FloatBarrier + +Στην εικόνα \ref{fig:cells-multiscale-bad} φαίνεται το αποτέλεσμα της πολυκλιμακωτής ανίχνευσης \eng{blobs} για τις τιμές παραμέτρων $\sigma = 3, \theta = 0.05, s = 1.1, N = 8$. Η ανίχνευση γίνεται σε 8 κλίμακες του $\sigma = 3$ με παράγοντα το 1.1 και χαμηλό κατώφλι.Αντιστοίχως, στην εικόνα \ref{fig:cells-multiscale-good} φαίνεται το αποτέλεσμα της πολυκλιμακωτής ανίχνευσης \eng{blobs} για τις τιμές παραμέτρων $\sigma = 3, \theta = 0.15, s = 1.1, N = 8$. Δηλαδή, η ανίχνευση γίνεται σε 8 κλίμακες του $\sigma = 3$ και με υψηλότερο κατώφλι, με παράγοντα το 1.1. + +Στην δε εικόνα \ref{fig:cells-multiscale-pair} παρατηρείται, ότι μειώνοντας το κατώφλι, όπως και στην μονοκλιμακωτή ανίχνευση, απορρίπτονται επιτυχώς κάποια ανεπιθύμητα \eng{blobs}. Μάλιστα, αυτό γίνεται εν προκειμένω με μεγαλύτερη επιτυχία, καθώς εξακολουθούν να ανιχνεύονται όλες οι λευκές περιοχές. Δεν απορρίπτεται, δηλαδή, κατά λάθος, κάποιο επιθυμητό \eng{blob}. Επομένως, συμπεραίνεται ότι η επέκταση της μεθόδου σε πολλαπλές κλίμακες είναι ευεργετική. + +\begin{figure}[h] + \centering + \begin{subfigure}{\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-cells-bad.jpg} + \caption{Χαμηλό κατώφλι} + \label{fig:cells-multiscale-bad} + \end{subfigure} + \begin{subfigure}{\textwidth} + \centering + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-cells-good.jpg} + \caption{Υψηλό κατώφλι} + \label{fig:cells-multiscale-good} + \end{subfigure} + \caption{Πολυκλιμακωτή ανίχνευση \eng{blobs} σε κύτταρα} + \label{fig:cells-multiscale-pair} +\end{figure} +\FloatBarrier + +\subsection{Επιτάχυνση Ανίχνευσης \eng{Blobs}} + +Η παραπάνω μέθοδος μπορεί να επιταχυνθεί \footnote{Σημειώνεται ότι η παρατηρούμενη επιτάχυνση εξαρτάται από την υλοποίηση της απλής μεθόδου ανίχνευσης \eng{blobs}. Βλέπε \ref{section:details}.} χρήσει ολοκληρωτικών εικόνων και \eng{box filter}. Συγκεκριμένα, ο υπολογισμός των μερικών παραγώγων μέχρι στιγμής απαιτούσε την συνέλιξη φίλτρων με την εκάστοτε εικόνα, γεγονός που τον καθιστούσε υπολογιστικά ακριβό. + +Οι ολοκληρωτικές εικόνες είναι μία τεχνική η οποία επιτρέπει των υπολογισμό συνελίξεων με την εικόνα σε χρόνο ανεξάρτητο του πυρήνα και εξαρτώμενο μόνο από το μέγεθος της εικόνας. Αυτό συμβαίνει, γιατί, χρήσει ολοκληρωτικών εικόνων, το άθροισμα των \eng{pixels} μίας ορθογώνιας περιοχής μπορεί να υπολογιστεί σε σταθερό χρόνο. Για να επιτευχθεί, όμως, η επιτάχυνση αυτή, χρησιμοποιείται μία προσέγγιση της παραγώγου. Επομένως, πρόκειται για προσεγγιστική μέθοδο και αναμένονται αποκλίσεις από τα προηγούμενα αποτελέσματα. + +Στην εικόνα \ref{fig:ii} φαίνονται τα αποτελέσματα της απόπειρας επιτάχυνσης της ανίχνευσης \eng{blobs} στις ίδιες εικόνες όπως προηγουμένως, στην οποία χρησιμοποιήθηκαν οι ίδιες ακριβώς παράμετροι όπως και στην απλή μέθοδο. + +Στην εικόνα \ref{fig:up-ii}, όπου χρησιμοποιείται μικρή τιμή της παραμέτρου $\sigma$, τα αποτελέσματα είναι πολύ ικανοποιητικά, καθώς εντοπίζονται επιτυχώς οι αντανακλάσεις φωτός επάνω στα μπαλόνια και, φυσικά, δεν αντιμετωπίζονται εσφαλμένες περιοχές ομοιογένειας. + +Στην δε εικόνα \ref{fig:cells-ii}, όπου χρησιμοποιείται μεγαλύτερη τιμή της παραμέτρου $\sigma$, τα αποτελέσματα δεν είναι το ίδιο ικανοποιητικά. Συγκεκριμένα, παρατηρείται ότι ανιχνεύονται μερικά ανεπιθύμητα \eng{blobs}, ωστόσο ανιχνεύονται και μερικά ορθώς. Επομένως, είναι εμφανές το γεγονός ότι η επιτάχυνση οφείλεται σε προσέγγιση. + +\begin{figure}[h] + \centering + \begin{subfigure}{\textwidth} + \includegraphics[width=\textwidth]{../image-plots/blob-detection-ii-up.jpg} + \caption{Αποτέλεσμα στην εικόνα \eng{Up}} + \label{fig:up-ii} + \end{subfigure} + \begin{subfigure}{\textwidth} + \includegraphics[width=\textwidth]{../image-plots/blob-detection-ii-cells.jpg} + \caption{Αποτέλεσμα στην εικόνα κυττάρων} + \label{fig:cells-ii} + \end{subfigure} + \caption{Προσέγγιση ανίχνευσης \eng{blobs} με ολοκληρωτικές εικόνες} + \label{fig:ii} +\end{figure} +\FloatBarrier + +\subsection{Επιτάχυνση Πολυκλιμακωτής Ανίχνευση \eng{Blobs}} + +Τα ίδια συμπεράσματα προκύπτουν και για την πολυκλιμακωτή ανίχνευση. + +\begin{figure}[h] + \centering + \begin{subfigure}{0.7\textwidth} + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-ii-up-scaled.jpg} + \caption{Αποτέλεσμα στην εικόνα \eng{Up}} + \label{fig:cells-multiscale-ii} + \end{subfigure} + \begin{subfigure}{0.7\textwidth} + \includegraphics[width=\textwidth]{../image-plots/blob-detection-multiscale-ii-cells-scaled.jpg} + \caption{Αποτέλεσμα στην εικόνα κυττάρων} + \label{fig:cells-multiscale-ii} + \end{subfigure} + \caption{Προσέγγιση πολυκλιμακωτής ανίχνευσης \eng{blobs} με ολοκληρωτικές εικόνες} +\end{figure} +\FloatBarrier + + +\newpage +\section{Παράρτημα} +\subsection{Επιτάχυνση χρήσει ολοκληρωτικών εικόνων και \eng{box filters}} +\label{section:details} + +Η παρατηρούμενη επιτάχυνση εξαρτάται και από την υλοποίηση τηςαπλής μεθόδου ανίχνευσης \eng{blobs}. Συγκεκριμένα, αν ο υπολογισμός των μερικών παραγώγων είχε γίνει χρήσει ''χειροποίητης`` συνάρτησης συνελίξεως δύο διαστάσεων, τότε η επιτάχυνση γίνεται αμέσως εμφανής. Ωστόσο, αν ο υπολογισμός μερικών παραγώγων είχε γίνει χρήσει έτοιμης συνάρτησης συνέλιξης από την βιβλιοθήκη \eng{cv2}, τότε η επιτάχυνση δεν θα είναι εμφανής. Αυτό συμβαίνει γιατί, κατόπιν μετρήσεων για διάφορες τιμές τις παραμέτρου $\sigma$, παρατηρήθηκε ότι η ταχύτητα της συνάρτησης \eng{cv2.filter2D} ήταν πρακτικά σταθερή. Το ίδιο παρατηρήθηκε και για την υλοποίηση χρήσει ολοκληρωτικών εικόνων και \eng{box filters}. Η δε ''χειροκίνητη`` υλοποίηση της διδιάστασης συνέλιξης εμφάνισε τετραγωνική χρονική εξάρτηση από την παράμετρο $\sigma$, όπως αναμενόταν. Τα συμπεράσματα παρουσιάζονται συνοπτικά στο ακόλουθο γράφημα \ref{fig:grad-comparison}. Αξιοσημειώτο είναι ότι, για την δίκαιη σύγκριση των αποτελεσμάτων, χρησιμοποιήθηκε ο \eng{Just-in-Time} μεταγλωττιστής \eng{Numba} για την βελτιστοποίηση των βρόχων \eng{for} στην υλοποίηση της διδιάστατης συνέλιξης. Παρ'όλα αυτά, η διαφορά στην απόδοση παραμένει σημαντική. + +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{../image-plots/grad-comparison.png} + \caption{Σύγκριση ταχύτητας διαφόρων υλοποιήσεων υπολογισμού μερικών παραγώγων} + \label{fig:grad-comparison} +\end{figure} +\FloatBarrier + + +\end{document} + diff --git a/lab1/source/live_developement.ipynb b/lab1/source/live_developement.ipynb new file mode 100644 index 0000000..5ab8d88 --- /dev/null +++ b/lab1/source/live_developement.ipynb @@ -0,0 +1,178 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "sys.path.append('../source')\n", + "import numpy as np\n", + "\n", + "from cv23_lab1_part3_utils import featuresSURF\n", + "from cv23_lab1_part3_utils import featuresHOG\n", + "from cv23_lab1_part3_utils import matching_evaluation\n", + "from cv23_lab1_part3_utils import FeatureExtraction\n", + "from corner_detection_utils import CornerDetection\n", + "from corner_detection_utils import HarrisLaplacian\n", + "from blob_detection_utils import BlobDetection\n", + "from blob_detection_utils import HessianLaplacian\n", + "from box_detection_utils import BoxLaplacian" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Image Matching" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "rotations = [-20, -10, 0, 10, 20]\n", + "escalations = [0.6, 0.8, 1.0, 1.2]\n", + "transformations = [(r, e) for r in rotations for e in escalations]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "descriptors = [lambda I, kp: featuresSURF(I, kp), lambda I, kp: featuresHOG(I, kp)]\n", + "detectors = [lambda i: CornerDetection(i, 2, 2.5, 0.005, 0.05),\n", + " lambda i: HarrisLaplacian(i, 2, 2.5, 0.005, 0.05, 1.1, 6),\n", + " lambda i: BlobDetection(i, 2, 0.005),\n", + " lambda i: HessianLaplacian(i, 2, 0.005, 1.1, 6),\n", + " lambda i: BoxLaplacian(i, 2, 0.005, 1.1, 6)]\n", + "descriptor_names = [\"featuresSURF\", \"featuresHOG\"]\n", + "detector_names = [\"CornerDetection\", \"HarrisLaplacian\", \"BlobDetection\", \"HessianLaplacian\", \"BoxLaplacian\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# this takes around 5 minutes\n", + "avg_scale_errors_list = np.zeros((len(descriptors), len(detectors), 3))\n", + "avg_theta_errors_list = np.zeros((len(descriptors), len(detectors), 3))\n", + "for index, descriptor in enumerate(descriptors):\n", + " for jndex, detector in enumerate(detectors):\n", + " avg_scale_errors_list[index, jndex], avg_theta_errors_list[index, jndex] = matching_evaluation(detector, descriptor)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"../report/avg_scale_errors.txt\", 'w') as file:\n", + " for index, descriptor in enumerate(descriptor_names):\n", + " for jndex, detector in enumerate(detector_names):\n", + " file.write(f\"{descriptor}, {detector} :\\t{avg_scale_errors_list[index, jndex]}\\n\")\n", + "with open(\"../report/avg_theta_errors.txt\", 'w') as file:\n", + " for index, descriptor in enumerate(descriptor_names):\n", + " for jndex, detector in enumerate(detector_names):\n", + " file.write(f\"{descriptor}, {detector} :\\t{avg_theta_errors_list[index, jndex]}\\n\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Feature Extraction" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "store_files = [\"./features/\"+detector+'_'+descriptor+\"store.txt\"\n", + " for detector in detector_names\n", + " for descriptor in descriptor_names]\n", + "load_files = [\"./features/\"+detector+'_'+descriptor+\"load.txt\"\n", + " for detector in detector_names\n", + " for descriptor in descriptor_names]\n", + "files = list(zip(store_files, load_files))\n", + "for store, load in files:\n", + " os.mknod(store)\n", + " os.mknod(load)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "detector_descriptor = [(detector, descriptor)\n", + " for detector in detectors\n", + " for descriptor in descriptors]\n", + "functions_and_files = list(zip(detector_descriptor, files))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Time for feature extraction: 28.270\n", + "Time for feature extraction: 27.687\n", + "Time for feature extraction: 221.835\n", + "Time for feature extraction: 167.192\n", + "Time for feature extraction: 23.660\n", + "Time for feature extraction: 33.143\n", + "Time for feature extraction: 179.042\n", + "Time for feature extraction: 130.931\n", + "Time for feature extraction: 186.082\n", + "Time for feature extraction: 125.283\n" + ] + } + ], + "source": [ + "features_list = [FeatureExtraction(detector, descriptor, saveFile=store)\n", + " for ((detector, descriptor), (store, load)) in functions_and_files]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cv_lab1_env", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.16" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lab2/README.md b/lab2/README.md new file mode 100644 index 0000000..4fd5eb6 --- /dev/null +++ b/lab2/README.md @@ -0,0 +1,76 @@ +Αυτό το εργαστήριο έχει τρία μέρη. + +1) Ανίχνευση Οπτικής Ροής +2) Κάτι που δεν άκουσα +3) Συνένωση Εικόνων + +Στα δύο πρώτα κυριαρχούν σήμερα τα νευρωνικά δίκτυα αλλά στην συνένωση +εικόνων ακόμα είναι δημοφιλείς οι παραδοσιακές μέθοδοι. + +Ξεκινάμε με κάτι φαινομενικά άσχετο, την ανίχνευση δέρματος. Αυτό, γιατί για να εφαρμόσουμε γενικά την κύρια τεχνική πρέπει να έχουμε βρει περιοχές ενδιαφέροντος. + +Ο rgb χώρος δεν είναι καλός για ανίχνευση δέρματος. Χρησιμοποιούνται άλλοι. +Το σημαντικό είναι να ικανοποιούνται τρία κριτήρια. +1) αντοχή σε αλλαγές φωτεινότητας +2) αντοχή σε διαφορετικά είδη δέρματος +3) κάτι για μικρές αποστάσεις που δεν πρόλαβα + +Εμείς μάλλον θα ασχοληθούμε με HSV αλλά το V δεν μας πολυενδιαφέρει, +άρα ουσιαστικά ασχολούμαστε με HS (hue saturation). +Έχει το μειονέκτημα ότι έχει σχετικά μεγάλο κόστος μετατροπής από rgb +σε hsv. Ο δε χώρος YCbCr έχει πιο γρήγορη μετατροπή. Τελικά, αυτός είναι +καλύτερος, γιατί εκεί αποδεικνύεται πειραματικά ότι το δέρμα ξεχωρίζεται +πιο εύκολα απ'ό,τι σε άλλους χώρους. + +# Προπαρασκευή + +Για το εργαστήριο, θα έχουμε κάποια δείγματα σημείων δέρματος και θα +ταιριάξουμε μία γκαουσσιανή κατανομή σε αυτά. Θα μπορούσε κανείς να +προσεγγίσει την κατανομή με περισσότερες γκαουσσιανές. Εμείς κάνουμε το +απλό. Αν εφαρμόσουμε, μετά, ένα πιθανοτικό κριτήριο στην εικόνα, τότε θα +έχουμε υψηλότερες πιθανότητες εκεί που όντως φαίνεται να υπάρχει δέρμα. Θα +εφαρμόσουμε ένα κατώφλι και θα πάρουμε τελικά τα σημεία του δέρματος. Μετά, +στην νέα εικόνα, θα κάνουμε άνοιγμα και κλείσιμο (κλείσιμο με μεγαλύτερο +δομικό στοιχείο αν κατάλαβα καλά) και μετά θα φράξουμε αυτές τις περιοχές +σε κουτάκια. + +# 1ο Μέρος Οπτική Ροή + +Διακρίνονται πυκνοί και αραιοί αλγόριθμοι οπτικής ροής. + +Αν ένας αλγόριθμος υπολογίζει την οπτική ροή σε όλη την εικόνα, +τότε χαρακτηρίζεται πυκνός. + +Αν υπολογίζει την οπτική ροή σε μία περιοχή της εικόνας μόνο, +τότε χαρακτηρίζεται αραίος. + +Οι δύο κύριοι αλγόριθμοι είναι Horn - Schmuk και Lucas - Kanade. Η διαφορά +τους είναι ότι, ο μεν υποθέτει ότι κάθε πίξελ έχει την δικιά του ταχύτητα +αλλά ότι αυτή δεν μεταβάλλεται κατά πολύ σε γειτονικά πίξελ, ο δε υποθέτει +ότι, σε ένα παράθυρο, η ταχύτητα παραμένει σταθερή, δηλαδή τα γειτονικά +πίξελ έχουν την ίδια ταχύτητα. + +Η λύση που προκύπτει για τον Lucas - Kanade είναι η ίδια με αυτήν που είχε +προκύψει για την ανίχνευση γωνιών. Δεν μπορεί να εφαρμοστεί, όμως, σε +οποιαδήποτε περιοχή της εικόνας. Πρέπει να εφαρμοστεί μόνο σε γωνίες, γιατί +ειδάλλως ο πίνακας που περιγράφει την λύση δεν είναι αντιστρέψιμος, άρα +ουσιαστικά δεν βρίσκεται λύση (σουπερ μαθηματική εξήγηση). Άρα, δεν +εφαρμόζεται σε ακμές, αλλά σε γωνίες. + +Το πρόβλημα είναι ότι υπολογίζει μόνο μικρές μετατοπίσεις, τύπου 1 με 2 +πίξελ. Για αυτόν τον λόγο, εφαρμόζεται η πολυκλιμακωτή εκδοχή του. +Μειώνεται η διάσταση του πίνακα και εφαρμόζεται εκεί ο αλγόριθμος. Έτσι, +αν στην εικόνα έχω μετατόπιση 10 πίξελ, τότε στην μικρή εικόνα, πχ διά 4, +θα έχω μετατόπιση 2.5 πίξελ. Έτσι, μεγάλες μετατοπίσεις μπορούν να αναχθούν +σε μικρές και να εντοπιστούν. Ουσιαστικά, οι μικρές μετατοπίσεις που +εντοπίζονται στις μικρές εικόνες σπρώχνουν τον αλγόριθμο στις μεγαλύτερες +εικόνες προς την σωστή κατεύθυνση για να εντοπίσουν την μεγάλη κίνηση. Σαν +ευνοϊκές αρχικές συνθήκες. + +Εμείς, λοιπόν, ουσιαστικά θα βρούμε τις γωνίες στις περιοχές δέρματος που +θα έχουμε εντοπίσει και θα εφαρμόσουμε εκεί τον αλγόριθμο. Θα βγαίνουν +γύρω στα 20-30 χαρακτηριστικά, για μία καλή τιμή κατωφλιού. Θέλουμε την ροή +μόνο στα χαρακτηριστικά αυτά. + + + diff --git a/lab2/final/lab2_report_03119051_03119058.pdf b/lab2/final/lab2_report_03119051_03119058.pdf new file mode 100644 index 0000000..a6d02b7 Binary files /dev/null and b/lab2/final/lab2_report_03119051_03119058.pdf differ diff --git a/lab2/final/part1/gifs/flow.gif b/lab2/final/part1/gifs/flow.gif new file mode 100644 index 0000000..d459a6d Binary files /dev/null and b/lab2/final/part1/gifs/flow.gif differ diff --git a/lab2/final/part1/gifs/flow_multiscale.gif b/lab2/final/part1/gifs/flow_multiscale.gif new file mode 100644 index 0000000..0170ac4 Binary files /dev/null and b/lab2/final/part1/gifs/flow_multiscale.gif differ diff --git a/lab2/final/part1/skin_detection.py b/lab2/final/part1/skin_detection.py new file mode 100644 index 0000000..391f6ef --- /dev/null +++ b/lab2/final/part1/skin_detection.py @@ -0,0 +1,47 @@ +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import scipy.io +import cv2 +import os + +NUM_IMAGES = 2 + +if __name__ == "__main__": + # load the skin samples that are stored in the + # same folder in .mat format in order to fit + # a gaussian curve on them. + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + # first convert the rgb values to ycbcr + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + # fit a gaussian curve on the skin samples + mu, cov = FitSkinGaussian(skin_samples) + print(f"Mean: {mu}") + print(f"Covariance: {cov}") + for i in range(1, 40, 5): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + + # convert the image to YCbCr color space + image_ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) + image_plot = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + boundaries = fd(image_ycrcb, mu, cov) + # draw the bounding boxes on the image + for boundary in boundaries: + # x, y, w, h = boundary + y, x, h, w = boundary + # cv2.rectangle(image, (y, x), (y+h, x+w), (0, 0, 255), 2) + cv2.rectangle(image_plot, (x, y), (x+w, y+h), (0, 255, 255), 2) + # show the image + fig, axs = plt.subplots(1, 1) + axs.imshow(image_plot) + axs.set_title(f"Skin detection on frame {i}") + # check if the results folder exists + # if not, create it + if not os.path.exists("results"): + os.makedirs("results") + plt.savefig(f"results/skin_detection_{i}.png") + + \ No newline at end of file diff --git a/lab2/final/part1/skin_detection_utils.py b/lab2/final/part1/skin_detection_utils.py new file mode 100644 index 0000000..0973444 --- /dev/null +++ b/lab2/final/part1/skin_detection_utils.py @@ -0,0 +1,83 @@ +import cv2 +import os +import numpy as np +from scipy import stats +from scipy import ndimage +import matplotlib.pyplot as plt + +SKIN_THRESHOLD = 0.05 + +def FitSkinGaussian(ycbcr_image): + """ Return mean and covariance of interest points' gaussian distribution + + Keyword arguments: + ycbcr_image -- input image in ycbcr color space. + """ + cbcr_image = ycbcr_image[:, :, 1:3] + height, width, channels = cbcr_image.shape + # calculate the average of cb and cr channels + mu = np.mean(cbcr_image.reshape(height*width, channels), axis=0) + # calculate the covariance of cb and cr channels + cov = np.cov(cbcr_image.reshape(height*width, channels).T) + return (mu, cov) + +def fd(image, mean, covariance): + """ Return bounding box of area of interest. + + Keyword arguments: + image -- the YCbCr input image. + mean -- the mean value of the gaussian distribution. + covariance -- the covariance of the gaussian distribution. + """ + # define the gaussian distribution according to the mean and covariance + distribution = stats.multivariate_normal(mean, covariance) + + # dstack means depth stack + # we give the Cb channel and the Cr channel + # and it forms an array of vectors (Cb, Cr) + pixels = np.dstack((image[:,:,1], image[:,:,2])) + # for the thresholding to work, it seems to be necessary to + # normalize the probability. i'm not sure why. + skin_image = (distribution.pdf(pixels)/np.max(distribution.pdf(pixels)) >= SKIN_THRESHOLD).astype('uint8') + + # save the binary skin image + plt.imshow(skin_image) + plt.title("Binary skin image before morphological operations") + # check if the results folder exists + # if not, create it + if not os.path.exists("results"): + os.makedirs("results") + plt.savefig("results/binary_skin_image.png") + + + # the skin image probably has holes + # we will attempt to close them by performing + # the opening with a small structural element and + # the closing with a bigger structural element + opening_strel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) + closing_strel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (19, 19)) + skin_image = cv2.morphologyEx(skin_image, cv2.MORPH_OPEN, opening_strel) + skin_image = cv2.morphologyEx(skin_image, cv2.MORPH_CLOSE, closing_strel) + + # save the binary skin image + plt.imshow(skin_image) + plt.title("Binary skin image after morphological operations") + plt.savefig("results/binary_skin_image_better.png") + # close the figure + plt.close() + + # find the connected components + # and return the bounding boxes of the + # connected components + labels, features = ndimage.label(skin_image) + boundaries = [] + for label in range(1, features+1): + # find the bounding box of the feature + # and append it to the list of boundaries + indices = np.where(labels == label) + y, x = indices[0], indices[1] + boundaries.append((np.min(y), np.min(x), np.max(y)-np.min(y), np.max(x)-np.min(x))) + return boundaries + + + diff --git a/lab2/final/part1/tracking.py b/lab2/final/part1/tracking.py new file mode 100644 index 0000000..53c99bd --- /dev/null +++ b/lab2/final/part1/tracking.py @@ -0,0 +1,87 @@ +from tracking_utils import lk +from tracking_utils import displ +from tracking_utils import makegif +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import numpy as np +import scipy.io +import cv2 + +NUM_IMAGES = 70 +STEP = 1 +AWESOME = False + +if __name__ == "__main__": + feats = 20 + padding = 20 + names = ["face", "right hand", "left hand"] + original = cv2.imread("part1-GreekSignLanguage/1.png") + initial = cv2.cvtColor(original, cv2.COLOR_BGR2YCR_CB) + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + mu, cov = FitSkinGaussian(skin_samples) + boundaries = fd(initial, mu, cov) + # find good features to track from the first image + # in each boundary + gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) + colours = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] + print(f"image.shape: {gray.shape}") + print(f"face: {boundaries[0]}") + print(f"right hand: {boundaries[1]}") + print(f"left hand: {boundaries[2]}") + dx0, dy0 = np.zeros(feats), np.zeros(feats) + for i in range(1, NUM_IMAGES): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image1 = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + image2 = cv2.imread(f"part1-GreekSignLanguage/{i+1}.png") + image_plot = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB) + gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) + gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) + + if AWESOME: + fig, axs = plt.subplots(2, 3) + axindices = {0: (0, 1), 1: (1, 2), 2: (1, 0)} + for j in range(2): + for k in range(3): + if (j, k) not in axindices.values(): + axs[j, k].axis("off") + for index, boundary in enumerate(boundaries): + y, x, h, w = boundary + # crop the image to retain only the pixels + # inside of the boundaries + cropped1 = gray1[y-padding:y+h+padding, x-padding:x+w+padding] + cropped2 = gray2[y-padding:y+h+padding, x-padding:x+w+padding] + features = np.squeeze(cv2.goodFeaturesToTrack(cropped2, feats, 0.05, 5).astype(int)) + [dx, dy] = lk(cropped1, cropped2, features, 2, 0.01, dx0, dy0) + + # compute the flow + [flowx, flowy] = displ(dx, dy, 0.7) + + # update the boundaries + x = int(round(x - flowx)) + y = int(round(y - flowy)) + boundaries[index] = (y, x, h, w) + + # show the new boundaries + cv2.rectangle(image_plot, (x, y), (x + w, y + h), colours[index], 2) + + # plot the flow like a gradient field + if AWESOME: + axs[axindices[index]].quiver(features[:, 0], features[:, 1], -dx, -dy, angles='xy') + axs[axindices[index]].set_title(f"Optical flow for {names[index]}") + + if AWESOME: + axs[1, 1].imshow(image_plot) + axs[1, 1].set_title(f"Frame {i+1}") + else: + plt.imshow(image_plot) + plt.title(f"Frame {i+1}") + plt.tight_layout() + # save the figure + plt.savefig(f"flow/n_{i+1}.png") + # makegif("flow/", "flow.gif") + + diff --git a/lab2/final/part1/tracking_multiscale.py b/lab2/final/part1/tracking_multiscale.py new file mode 100644 index 0000000..b896d83 --- /dev/null +++ b/lab2/final/part1/tracking_multiscale.py @@ -0,0 +1,86 @@ +from tracking_utils import multiscale_lk +from tracking_utils import displ +from tracking_utils import makegif +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import numpy as np +import scipy.io +import cv2 + +AWESOME = False + +if __name__ == "__main__": + feats = 20 + padding = 20 + scales = 3 + names = ["face", "right hand", "left hand"] + original = cv2.imread("part1-GreekSignLanguage/1.png") + initial = cv2.cvtColor(original, cv2.COLOR_BGR2YCR_CB) + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + mu, cov = FitSkinGaussian(skin_samples) + boundaries = fd(initial, mu, cov) + # find good features to track from the first image + # in each boundary + gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) + colours = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] + print(f"image.shape: {gray.shape}") + boundaries = fd(initial, mu, cov) + print(f"face: {boundaries[0]}") + print(f"right hand: {boundaries[1]}") + print(f"left hand: {boundaries[2]}") + dx0, dy0 = np.zeros(feats), np.zeros(feats) + for i in range(1, 69): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image1 = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + image2 = cv2.imread(f"part1-GreekSignLanguage/{i+1}.png") + image_plot = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB) + gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) + gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) + + if AWESOME: + fig, axs = plt.subplots(2, 3) + axindices = {0: (0, 1), 1: (1, 2), 2: (1, 0)} + for j in range(2): + for k in range(3): + if (j, k) not in axindices.values(): + axs[j, k].axis("off") + for index, boundary in enumerate(boundaries): + y, x, h, w = boundary + # crop the image to retain only the pixels + # inside of the boundaries + cropped1 = gray1[y-padding:y+h+padding, x-padding:x+w+padding] + cropped2 = gray2[y-padding:y+h+padding, x-padding:x+w+padding] + [dx, dy] = multiscale_lk(cropped1, cropped2, feats, 2, 0.01, scales) + + # compute the flow + [flowx, flowy] = displ(dx, dy, 0.7) + + # update the boundaries + x = int(round(x - flowx)) + y = int(round(y - flowy)) + boundaries[index] = (y, x, h, w) + + # show the new boundaries + cv2.rectangle(image_plot, (x, y), (x + w, y + h), colours[index], 2) + + # plot the flow like a gradient field + if AWESOME: + features = np.squeeze(cv2.goodFeaturesToTrack(cropped2, feats, 0.05, 5).astype(int)) + axs[axindices[index]].quiver(features[:, 0], features[:, 1], -dx, -dy, angles='xy') + axs[axindices[index]].set_title(f"Optical flow for {names[index]}") + if AWESOME: + axs[1, 1].imshow(image_plot) + axs[1, 1].set_title(f"Frame {i}") + else: + plt.imshow(image_plot) + plt.title(f"Frame {i}") + plt.tight_layout() + # save the figure + plt.savefig(f"flow_multiscale/n_{i}.png") + # makegif("flow_multiscale/", "flow_multiscale.gif") + + diff --git a/lab2/final/part1/tracking_utils.py b/lab2/final/part1/tracking_utils.py new file mode 100644 index 0000000..1b7fad9 --- /dev/null +++ b/lab2/final/part1/tracking_utils.py @@ -0,0 +1,193 @@ +import numpy as np +import imageio +import cv2 +from scipy.ndimage import map_coordinates + +def lk(i1, i2, features, rho, epsilon, dx0, dy0): + """ Lucas-Kanade algorithm + + Keyword arguments: + i1 -- initial frame + i2 -- next frame + features -- coordinates of interest-points + rho -- gaussian width parameter + epsilon -- minimum constant to avoid zeroes + dx0 -- initial guesses for movement of features in x axis + dy0 -- initial guesses for movement of features in y axis + returns -- [dx, dy] actual estimates for movement of features + """ + # first define a helper function that + # accomodated the shifting of images + def shift_image(image, shift): + """ Shift the image + + Keyword arguments: + image -- image to be shifted + shift -- shift amount + """ + dx, dy = shift + x, y = np.meshgrid(np.arange(image.shape[1]), np.arange(image.shape[0])) + return map_coordinates(image,[np.ravel(y + dy), np.ravel(x + dx)], order=1).reshape(image.shape) + + # convert the images to float in [0,1] + # for the parameters to make sense + i1 = i1.astype(np.float)/255 + i2 = i2.astype(np.float)/255 + # define limit of iterations + # and threshold of change + limit = 150 + threshold = 0.001 + # setup the kernel for the convolutions + # this kernel acts as a gaussian filter + size = int(2*np.ceil(3*rho)+1) + mid = (size-1)//2 + kernel = cv2.getGaussianKernel(size, rho) + kernel = kernel @ kernel.T + + # initialize result vectors + returnx = np.zeros(len(features)) + returny = np.zeros(len(features)) + + for index, feature in enumerate(features): + # get the coordinates of the feature + x, y = feature + # get area around the feature in both images + initial_image = i1[max(0, y-mid):min(y+mid, i1.shape[0]), + max(0, x-mid):min(x+mid, i1.shape[1])] + next_image = i2[max(0, y-mid):min(y+mid, i2.shape[0]), + max(0, x-mid):min(x+mid, i2.shape[1])] + # compute the gradient of the initial image + gradient_y, gradient_x = np.gradient(initial_image) + + # initialize iteration counter and change + iterations = 0 + change = float('inf') + dy, dx = dy0[index], dx0[index] + while (iterations < limit and change > threshold): + # shift the initial image by the current displacement + shifted_image = shift_image(initial_image, [dx, dy]) + # shift the gradient of the initial image by the current displacement + shifted_gradient_x = shift_image(gradient_x, [dx, dy]) + shifted_gradient_y = shift_image(gradient_y, [dx, dy]) + # compute the error between the shifted image and the next image + error = next_image - shifted_image + # compute the Lucas-Kanade equations + s11 = cv2.filter2D(shifted_gradient_x**2, -1, kernel)[mid,mid] + epsilon + s12 = cv2.filter2D(shifted_gradient_x*shifted_gradient_y, -1, kernel)[mid,mid] + s22 = cv2.filter2D(shifted_gradient_y**2, -1, kernel)[mid,mid] + epsilon + b1 = cv2.filter2D(shifted_gradient_x*error, -1, kernel)[mid,mid] + b2 = cv2.filter2D(shifted_gradient_y*error, -1, kernel)[mid,mid] + # compute the determinant of the system + det = s11*s22 - s12*s12 + # compute the improvement + delta_x = (s22*b1 - s12*b2)/det + delta_y = (s11*b2 - s12*b1)/det + # update the displacement estimates + dx += delta_x + dy += delta_y + # compute the change + change = np.linalg.norm([delta_x, delta_y]) + # update the number of iterations + iterations += 1 + # update the displacement estimates + returnx[index] = dx + returny[index] = dy + return np.array([returnx, returny]) + +def multiscale_lk(i1, i2, num_features, rho, epsilon, scale): + """ Multiscale Lucas-Kanade algorithm + + Keyword arguments: + i1 -- initial frame + i2 -- next frame + num_features -- number of features to track + rho -- gaussian width parameter + epsilon -- minimum constant to avoid zeroes + scale -- number of scales in the pyramid + returns -- [dx, dy] actual estimates for movement of features + """ + # first define some helper functions + # that do not need to be visible outside + # of this function + def pyramid(image, levels): + """ Create a pyramid of images + + Keyword arguments: + image -- image to be scaled + levels -- number of levels in the pyramid + """ + + def downscale(image): + """ Downscale the image by a factor of 2 + + Keyword arguments: + image -- image to be downscaled + """ + gauss = cv2.getGaussianKernel(3, 1) + gauss = gauss @ gauss.T + return cv2.filter2D(image, -1, gauss)[::2,::2] + + result = [image] + for i in range(levels - 1): + result.append(downscale(result[i])) + + result.reverse() + return result + + # we should normalize the images, + # but we do not need to do it here + # because we already do it in lk. + + # therefore, build the pyramids + # with the original images + # from deep level to shallow level. + pyramid1 = pyramid(i1, scale) + pyramid2 = pyramid(i2, scale) + + # initialize result vectors. + dx0, dy0 = np.zeros(num_features), np.zeros(num_features) + + for level in range(scale): + features = np.squeeze(cv2.goodFeaturesToTrack(pyramid2[level], num_features, 0.05, 5).astype(int)) + + [dx, dy] = lk(pyramid1[level], pyramid2[level], features, rho, epsilon, dx0, dy0) + [flowx, flowy] = displ(dx, dy, 0.7) + # update the initial guesses + if level < scale - 1: + dx0 = np.full((num_features), 2*flowx) + dy0 = np.full((num_features), 2*flowy) + + return np.array([dx, dy]) + +def displ(dx, dy, threshold): + """ Display the optical flow + + Keyword arguments: + dx -- displacement x axis + dy -- displacement y axis + threshold -- threshold for the optical flow + """ + energies = np.array([x**2 + y**2 for x, y in zip(dx, dy)]) + mean_energy = np.mean(energies) + energy = np.array([np.array([dx, dy]) + for x, y in zip(dx, dy) + if (x**2 + y**2) > threshold*mean_energy]) + + # check if there are any features + # with enough energy + if energy.shape[0] == 0: + return [0, 0] + return [np.mean(energy[:,0]), np.mean(energy[:,1])] + +def makegif(path, name): + images = [] + for i in range(1, 69): + print(path + str(i+1) + '.png') + img = cv2.imread(path + str(i+1) + '.png',1) + #check if image is empty + if img is None: + print('Image is empty') + return + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + images.append(img) + imageio.mimsave('gifs/'+name, images) \ No newline at end of file diff --git a/lab2/final/part2/.vscode/settings.json b/lab2/final/part2/.vscode/settings.json new file mode 100644 index 0000000..cad7657 --- /dev/null +++ b/lab2/final/part2/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/lab2/final/part2/classification.py b/lab2/final/part2/classification.py new file mode 100644 index 0000000..020c9b3 --- /dev/null +++ b/lab2/final/part2/classification.py @@ -0,0 +1,211 @@ +import os +import numpy as np +import random +import pickle +from itertools import product +from detector_utils import get_hog_hof, get_hof_descriptors, get_hog_descriptors, GaborDetector, HarrisDetector, MultiscaleDetector +from cv23_lab2_2_utils import bag_of_words, read_video, svm_train_test + +NBINS = 10 +NUM_FRAMES = 200 + +TRAIN_NAMES_FILE = "train_names.txt" +TEST_NAMES_FILE = "test_names.txt" + +VIDEO_FOLDER = "SpatioTemporal/{label}" + +# define dictionary for multiple tests +# each test is a dictionary with keys: +# scale, detector, descriptor, points + +PARAMETERS = { + "scale": ["multiscale"], + "detector": ["gabor", "harris"], + "descriptor": ["hog_hof", "hog", "hof"], + "points": [500] # if we want to test more points, we have to lower the thresholds. +} + +DESCRIPTORS_FILE = "classification_descriptors/{scale}_{detector}_{descriptor}_{points}.pickle" +RESULTS_FILE = "classification_results/{scale}_{detector}_{descriptor}_{points}.txt" + +def init_detectors(scale, detector): + """ + Returns the detector function. + + Keyword arguments: + scale -- the scale of the detector + detector -- the detector to use + """ + print("\n\tInitializing detector...") + if scale == "multiscale": + if detector == "harris": + detector = lambda video, points: MultiscaleDetector(lambda video, sigma, tau: + HarrisDetector(video, 2, sigma, tau, kappa=0.005, threshold=0.05, num_points=points), + video, [4*(1.1**i) for i in range(8)], tau=1.5, num_points=points) + elif detector == "gabor": + detector = lambda video, points: MultiscaleDetector(lambda video, sigma, tau: + GaborDetector(video, sigma, tau, threshold=0.1, num_points=points), + video, [4*(1.1**i) for i in range(8)], tau=1.5, num_points=points) + else: + raise ValueError("DETECTOR must be either 'harris' or 'gabor'") + elif scale == "uniscale": + if detector == "harris": + detector = lambda video, points: HarrisDetector(video, s=2, sigma=4, tau=1.5, + kappa=0.005, threshold=0.05, num_points=points) + elif detector == "gabor": + detector = lambda video, points: GaborDetector(video, sigma=4, tau=1.5, + threshold=0.25, num_points=points) + else: + raise ValueError("DETECTOR must be either 'harris' or 'gabor'") + print("\tFinished ...") + return detector + +def init_descriptors(descriptor): + """ + Returns the get_descriptors function. + + Keyword arguments: + descriptor -- the descriptor to use + """ + print("\n\tInitializing descriptor...") + if descriptor == "hog": + get_descriptors = lambda video, points: get_hog_descriptors(video, points, nbins=NBINS) + elif descriptor == "hof": + get_descriptors = lambda video, points: get_hof_descriptors(video, points, nbins=NBINS) + elif descriptor == "hog_hof": + get_descriptors = lambda video, points: get_hog_hof(video, points, nbins=NBINS) + else: + raise ValueError("DESCRIPTOR must be either 'hog', 'hof' or 'hog_hof'") + print("\tFinished ...") + return get_descriptors + +def get_names(): + """ + Returns the train and test names. + If train_names.txt and test_names.txt exist, + it loads them. + Otherwise, it creates them. + """ + print("\n\tGetting names...") + # check if train_names.txt and test_names.txt exist + # if they exist, load them: + if os.path.exists(TRAIN_NAMES_FILE) and os.path.exists(TEST_NAMES_FILE): + # read them + with open(TRAIN_NAMES_FILE, "r") as f: + train_names = f.read().splitlines() + with open(TEST_NAMES_FILE, "r") as f: + test_names = f.read().splitlines() + # otherwise, create them: + else: + # get all the video names with full path + # from current directory + video_names = [] + for label in ["handwaving", "running", "walking"]: + video_names += [os.path.join(VIDEO_FOLDER.format(label=label), video_name) + for video_name in os.listdir(VIDEO_FOLDER.format(label=label))] + + # shuffle them + random.shuffle(video_names) + + # split them into train and test + train_names = video_names[:int(0.7*len(video_names))] + test_names = video_names[int(0.7*len(video_names)):] + + # save them + with open(TRAIN_NAMES_FILE, "w") as f: + f.write("\n".join(train_names)) + with open(TEST_NAMES_FILE, "w") as f: + f.write("\n".join(test_names)) + print("\tFinished ...") + return train_names, test_names + +def extract_descriptors(names, detector, get_descriptors, points): + """ + Extracts the descriptors from the videos. + + Keyword arguments: + names -- the names of the videos + detector -- the detector to use + get_descriptors -- the descriptor to use + points -- the number of points to use + """ + print("\n\tExtracting descriptors...") + descriptors = [] + for name in names: + video = read_video(name, NUM_FRAMES, 0) + interest = detector(video, points) + descs = get_descriptors(video, interest) + descriptors.append(descs) + print("\tChecking if all descriptors have the same shape...") + original_shape = descriptors[0].shape + print(f"\toriginal_shape: {original_shape}") + for index, descriptor in enumerate(descriptors): + if descriptor.shape != original_shape: + raise ValueError(f"All descriptors must have the same shape. Descriptor {index} has shape {descriptor.shape}") + print("\tFinished ...") + return descriptors + +def run_test(scale, detector, descriptor, points): + """ + Runs the test for the current parameters. + + Saves the descriptors in a pickle file. + Saves the results in a text file. + + Keyword arguments: + scale -- the scale of the detector + detector -- the detector to use + descriptor -- the descriptor to use + points -- the number of points to use + """ + fun_detector = init_detectors(scale, detector) + get_descriptors = init_descriptors(descriptor) + train_names, test_names = get_names() + + # Define a dictionary for label mappings + label_mappings = { "handwaving": 0, "running": 1, "walking": 2 } + + # Generate test_labels + test_labels = [label_mappings[name.split("_")[1]] for name in test_names] + # Generate train_labels + train_labels = [label_mappings[name.split("_")[1]] for name in train_names] + + # check if descriptors have already been computed + if os.path.exists(DESCRIPTORS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points)): + print("\n\tLoading descriptors...") + with open(DESCRIPTORS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points), "rb") as f: + descriptors = pickle.load(f) + test_descriptors = descriptors["test"] + train_descriptors = descriptors["train"] + else: + # Extract descriptors + test_descriptors = extract_descriptors(test_names, fun_detector, get_descriptors, points) + train_descriptors = extract_descriptors(train_names, fun_detector, get_descriptors, points) + + # train and test + bow_train, bow_test = bag_of_words(train_descriptors, test_descriptors, num_centers=50) + accuracy, pred = svm_train_test(bow_train, train_labels, bow_test, test_labels) + with open(RESULTS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points), "w") as f: + f.write("Accuracy: {accuracy}\n".format(accuracy=accuracy)) + f.write("Predictions: {pred}\n".format(pred=pred)) + f.write("Test labels: {test_labels}\n".format(test_labels=test_labels)) + + with open(DESCRIPTORS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points), "wb") as f: + pickle.dump({"test": test_descriptors, "train": train_descriptors}, f) + +def main(): + keys = PARAMETERS.keys() + combinations = product(*[PARAMETERS[key] for key in keys]) + for combination in combinations: + scale, detector, descriptor, points = combination + # run the test + print(f"Test: scale={scale}, detector={detector}, descriptor={descriptor}, points={points}") + run_test(scale, detector, descriptor, points) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/lab2/final/part2/detector_utils.py b/lab2/final/part2/detector_utils.py new file mode 100644 index 0000000..b7398b7 --- /dev/null +++ b/lab2/final/part2/detector_utils.py @@ -0,0 +1,293 @@ +import cv2 +import numba +import numpy as np +import scipy.ndimage as scp +from cv23_lab2_2_utils import orientation_histogram + +def video_gradients(video): + """ + Compute the gradients of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) normalized to [0, 1] + """ + # compute gradients + Ly = scp.convolve1d(video, np.array([-1, 0, 1]), axis=0) + Lx = scp.convolve1d(video, np.array([-1, 0, 1]), axis=1) + Lt = scp.convolve1d(video, np.array([-1, 0, 1]), axis=2) + return Ly, Lx, Lt + +def video_smoothen(video, space_kernel, time_kernel): + """ + Smoothen a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) normalized to [0, 1] + space_kernel -- Gaussian kernel space standard deviation + time_kernel -- Gaussian kernel time standard deviation + """ + video = scp.convolve1d(video, space_kernel, axis=0) + video = scp.convolve1d(video, space_kernel, axis=1) + video = scp.convolve1d(video, time_kernel, axis=2) + return video + +def video_smoothen_space(video, sigma): + """ + Smoothen a video in space. + + Keyword arguments: + video -- input video (y_len, x_len, frames) normalized to [0, 1] + sigma -- Gaussian kernel space standard deviation + """ + # define Gaussian kernel + space_size = int(2*np.ceil(3*sigma)+1) + kernel = cv2.getGaussianKernel(space_size, sigma).T[0] + # smoothen the video + video = scp.convolve1d(video, kernel, axis=0) + video = scp.convolve1d(video, kernel, axis=1) + return video + +def interest_points(response, num, threshold, scale): + """ + Find interest points in a video. + + Keyword arguments: + response -- response (y_len, x_len, frames) + num -- number of interest points + threshold -- threshold + scale -- scale + """ + maxr = np.max(response.flatten()) + x, y, t = np.where(response > threshold*maxr) + points = np.column_stack((y, x, t, scale*np.ones(len(x)))) + + # Sort points based on response values in descending order + response_values = response[x, y, t] + sorted_indices = np.argsort(response_values)[::-1] # Sort in descending order + + # Select the top 'num' points + top_points = points[sorted_indices[:num]] + return top_points + +def HarrisDetector(v, s, sigma, tau, kappa, threshold, num_points): + """ + Harris Corner Detector + + Keyword arguments: + video -- input video (y_len, x_len, frames) + s -- Gaussian kernel size + sigma -- Gaussian kernel space standard deviation + tau -- Gaussian kernel time standard deviation + rho -- Harris response threshold + """ + # define Gaussian kernel + space_size = int(2*np.ceil(3*sigma)+1) + time_size = int(2*np.ceil(3*tau)+1) + space_kernel = cv2.getGaussianKernel(space_size, sigma).T[0] + time_kernel = cv2.getGaussianKernel(time_size, tau).T[0] + # setup video + video = v.copy() # copy so we don't modify the original + video = video.astype(float)/video.max() + video = video_smoothen(video, space_kernel, time_kernel) + # compute gradients + Ly, Lx, Lt = video_gradients(video) + # define Gaussian kernel + space_size = int(2*np.ceil(3*s*sigma)+1) + time_size = int(2*np.ceil(3*s*tau)+1) + space_kernel = cv2.getGaussianKernel(space_size, s*sigma).T[0] + time_kernel = cv2.getGaussianKernel(time_size, s*tau).T[0] + # smoothen the gradient products + Lxy = video_smoothen(Lx * Ly, space_kernel, time_kernel) + Lxt = video_smoothen(Lx * Lt, space_kernel, time_kernel) + Lyt = video_smoothen(Ly * Lt, space_kernel, time_kernel) + Lxx = video_smoothen(Lx * Lx, space_kernel, time_kernel) + Lyy = video_smoothen(Ly * Ly, space_kernel, time_kernel) + Ltt = video_smoothen(Lt * Lt, space_kernel, time_kernel) + # compute Harris response + trace = Lxx + Lyy + Ltt + det = Lxx*(Lyy*Ltt - Lyt*Lyt) - Lxy*(Lxy*Ltt - Lyt*Lxt) + Lxt*(Lxy*Lyt - Lyy*Lxt) + response = (det - kappa * trace * trace * trace) + # find interest points + points = interest_points(response, num=num_points, threshold=threshold, scale=sigma) + return points + +def GaborDetector(v, sigma, tau, threshold, num_points): + """ + Gabor Detector + + Keyword arguments: + video -- input video (y_len, x_len, frames) + sigma -- Gaussian kernel space standard deviation + tau -- Gaussian kernel time standard deviation + kappa -- Gabor response threshold + """ + # setup video + video = v.copy() + video = video.astype(float)/video.max() + video = video_smoothen_space(video, sigma) + # first define a linspace of width -2tau to 2tau + time = np.linspace(-2*tau, 2*tau, int(4*tau+1)) + omega = 4/tau + # define the gabor filters + h_ev = np.exp(-time**2/(2*tau**2)) * np.cos(2*np.pi*omega*time) + h_od = np.exp(-time**2/(2*tau**2)) * np.sin(2*np.pi*omega*time) + # normalize the L1 norm + h_ev /= np.linalg.norm(h_ev, ord=1) + h_od /= np.linalg.norm(h_od, ord=1) + # compute the response + response = (scp.convolve1d(video, h_ev, axis=2) ** 2) + (scp.convolve1d(video, h_od, axis=2) ** 2) + points = interest_points(response, num=num_points, threshold=threshold, scale=sigma) + return points + +def MultiscaleDetector(detector, video, sigmas, tau, num_points): + """ + Multiscale Detector + + Executes a detector at multiple scales. Detector has to be a function that + takes a video as input, along with other parameters, and returns a list of interest points. + + + Keyword arguments: + detector -- function that returns interest points + video -- input video (y_len, x_len, frames) + sigmas -- list of scales + """ + # FIXME: probably needs refactoring. + # the code is clear but super inefficient. + # the gradients are computed a gazillion times. + + # for every scale, compute the Harris response + points = [] + for sigm in sigmas: + found = detector(video, sigm, tau) + points.append(found) + return LogMetricFilter(video, points, tau, num_points) + +def LogMetricFilter(video, points_per_scale, tau, num_points): + """ + Filters interest points according to the log metric + + Keyword arguments: + video -- input video (y_len, x_len, frames) + points_per_scale -- list of interest points + """ + def LogMetric(logs, itemsperscale, N): + # log((x,y), s) = (s^2)|Lxx((x,y),s) + Lyy((x,y),s)| + # returns the coordinates of the points that maximize + # the log metric in a neighborhood of 3 scales + # (prev scale), (curr scale), (next scale) + final = [] + final_logs = [] + for index, items in enumerate(itemsperscale): + logp = logs[max(index-1,0)] + logc = logs[index] + logn = logs[min(index+1,N-1)] + for triplet in items: + y, x, t = int(triplet[0]), int(triplet[1]), int(triplet[2]) + prev = logp[x, y, t] + curr = logc[x, y, t] + next = logn[x, y, t] + if (curr >= prev) and (curr >= next): + final.append(triplet) + final_logs.append(curr) + # get the points with top num_points log metric values + if len(final) > num_points: + indices = np.argsort(final_logs)[::-1] + final_points = [final[i] for i in indices[:num_points]] + return np.array(final_points) + else: + return np.array(final) + v = video.copy() + vnorm = v.astype(float)/video.max() + # compute the laplacian of gaussian (log) metric + logs = [] + time_size = int(2*np.ceil(3*tau)+1) + time_kernel = cv2.getGaussianKernel(time_size, tau).T[0] + # get the sigmas from the points + sigmas = [item[0, 3] for item in points_per_scale] + for sigma in sigmas: + # define Gaussian kernel + space_size = int(2*np.ceil(3*sigma)+1) + space_kernel = cv2.getGaussianKernel(space_size, sigma).T[0] + v = video_smoothen(vnorm, space_kernel, time_kernel) + # compute gradients + Ly, Lx, _ = video_gradients(v) + # compute second order derivatives + Lyy, _, _ = video_gradients(Ly) + _, Lxx, _ = video_gradients(Lx) + # compute the log metric + log = (sigma**2) * np.abs(Lxx + Lyy) + logs.append(log) + # find the points that maximize the log metric + return LogMetric(logs, points_per_scale, len(points_per_scale)) + +def get_hog_descriptors(video, interest_points, nbins): + """ + Compute the HOG descriptors of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) + interest_points -- interest points (y, x, t, s) + sigma -- Gaussian kernel space standard deviation + nbins -- number of bins + """ + # gradients + Ly, Lx, _ = video_gradients(video.astype(float)) + descriptors = [] + for point in interest_points: + side = int(round(4*point[3])) + leftmost = int(max(0, point[0]-side)) + rightmost = int(min(video.shape[1]-1, point[0]+side+1)) + upmost = int(max(0, point[1]-side)) + downmost = int(min(video.shape[0]-1, point[1]+side+1)) + + descriptor = orientation_histogram(Lx[upmost:downmost, leftmost:rightmost, int(point[2])], + Ly[upmost:downmost, leftmost:rightmost, int(point[2])], + nbins, np.array([side, side])) + descriptors.append(descriptor) + return np.array(descriptors, dtype=object) + +def get_hof_descriptors(video, interest_points, nbins): + """ + Compute the HOF descriptors of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) + interest_points -- interest points (y, x, t, s) + sigma -- Gaussian kernel space standard deviation + nbins -- number of bins + """ + oflow = cv2.DualTVL1OpticalFlow_create(nscales=1) + descriptors = [] + for point in interest_points: + side = int(round(4*point[3])) + leftmost = int(max(0, point[0]-side)) + rightmost = int(min(video.shape[1]-1, point[0]+side+1)) + upmost = int(max(0, point[1]-side)) + downmost = int(min(video.shape[0]-1, point[1]+side+1)) + + flow = oflow.calc(video[upmost:downmost, leftmost:rightmost, int(point[2]-1)], + video[upmost:downmost, leftmost:rightmost, int(point[2])], None) + descriptor = orientation_histogram(flow[...,0], flow[...,1], + nbins, np.array([side, side])) + descriptors.append(descriptor) + return np.array(descriptors, dtype=object) + +def get_hog_hof(video, interest_points, nbins): + """ + Compute the HOG and HOF descriptors of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) + interest_points -- interest points (y, x, t, s) + sigma -- Gaussian kernel space standard deviation + nbins -- number of bins + """ + hog = get_hog_descriptors(video, interest_points, nbins) + print("HOG: ", hog.shape) + hof = get_hof_descriptors(video, interest_points, nbins) + print("HOF: ", hof.shape) + return np.concatenate((hog, hof)) + + + diff --git a/lab2/final/part2/gabor.py b/lab2/final/part2/gabor.py new file mode 100644 index 0000000..9e980a3 --- /dev/null +++ b/lab2/final/part2/gabor.py @@ -0,0 +1,43 @@ +import os +import sys +import random +from itertools import product +from detector_utils import GaborDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + +RESULTS_FOLDER = "results_trial/gabor_{sigma}_{tau}_{threshold}_{num_points}" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] +PARAMETERS = { + "sigma": [2, 3, 4, 5], + "tau": [1.5, 2, 2.5, 3], + "threshold": [0.1, 0.15, 0.2, 0.25, 0.3], + "num_points": [500] +} + +if __name__ == "__main__": + num_frames = {"walking": 70, "running": 50, "handwaving": 50} + # pick a random video from every category + # find the interest points and save them + combinations = product(*PARAMETERS.values()) + for combination in combinations: + sigma, tau, threshold, num_points = combination + results_folder = RESULTS_FOLDER.format(sigma=sigma, tau=tau, threshold=threshold, num_points=num_points) + for category in CATEGORIES: + frames = num_frames[category] + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, frames, 0) + # get the interest points + gabor_points = GaborDetector(video, sigma, tau, threshold, num_points) + # save the interest points + if not os.path.exists(os.path.join(results_folder, category)): + os.makedirs(os.path.join(results_folder, category)) + show_detection(video, gabor_points, save_path=os.path.join(results_folder, category)) + + diff --git a/lab2/final/part2/harris.py b/lab2/final/part2/harris.py new file mode 100644 index 0000000..fb5e406 --- /dev/null +++ b/lab2/final/part2/harris.py @@ -0,0 +1,41 @@ +import os +import sys +import random +from itertools import product +from detector_utils import HarrisDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + + +RESULTS_FOLDER = "results_trial/harris_{sigma}_{tau}_{threshold}_{num_points}" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] +PARAMETERS = { + "sigma": [2, 3, 4, 5], + "tau": [1.5, 2, 2.5, 3], + "kappa": [0.005], + "threshold": [0.15], + "num_points": [500] +} + +if __name__ == "__main__": + num_frames = 100 + combinations = product(*PARAMETERS.values()) + for combination in combinations: + sigma, tau, kappa, threshold, num_points = combination + results_folder = RESULTS_FOLDER.format(sigma=sigma, tau=tau, threshold=threshold, num_points=num_points) + for category in CATEGORIES: + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, num_frames, 0) + # get the interest points + harris_points = HarrisDetector(video, s=2, sigma=sigma, tau=tau, kappa=0.005, + threshold=threshold, num_points=num_points) + # save the interest points + if not os.path.exists(os.path.join(results_folder, category)): + os.makedirs(os.path.join(results_folder, category)) + show_detection(video, harris_points, save_path=os.path.join(results_folder, category)) \ No newline at end of file diff --git a/lab2/final/part2/multiscale_gabor.py b/lab2/final/part2/multiscale_gabor.py new file mode 100644 index 0000000..30d6b34 --- /dev/null +++ b/lab2/final/part2/multiscale_gabor.py @@ -0,0 +1,33 @@ +import os +import sys +import random +from detector_utils import GaborDetector +from detector_utils import MultiscaleDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + +RESULTS_FOLDER = "results" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] + +if __name__ == "__main__": + num_frames = 100 + # pick a random video from every category + # find the interest points and save them + for category in CATEGORIES: + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, num_frames, 0) + # get the interest points + gabor_points = MultiscaleDetector(lambda video, sigma, tau: + GaborDetector(video, sigma, tau, threshold=0.3, num_points=500), + video, sigmas=[3*(1.1**i) for i in range(6)], tau=1.5, num_points=500) + # save the detection + # check that folder exists + if not os.path.exists(os.path.join(RESULTS_FOLDER, "multiscale_gabor", category)): + os.makedirs(os.path.join(RESULTS_FOLDER, "multiscale_gabor", category)) + show_detection(video, gabor_points, save_path=os.path.join(RESULTS_FOLDER, "multiscale_gabor", category)) diff --git a/lab2/final/part2/multiscale_harris.py b/lab2/final/part2/multiscale_harris.py new file mode 100644 index 0000000..b8c7bad --- /dev/null +++ b/lab2/final/part2/multiscale_harris.py @@ -0,0 +1,35 @@ +import os +import sys +import random +from detector_utils import HarrisDetector +from detector_utils import MultiscaleDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + +RESULTS_FOLDER = "results" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] + +if __name__ == "__main__": + num_frames = 100 + # pick a random video from every category + # find the interest points and save them + for category in CATEGORIES: + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, num_frames, 0) + # get the interest points + + harris_points = MultiscaleDetector(lambda video, sigma, tau: + HarrisDetector(video, 2, sigma, tau, kappa=0.005, threshold=0.05, num_points=500), + video, [3*(1.1**i) for i in range(8)], tau=1.5, num_points=500) + # save the detection + # check that folder exists + if not os.path.exists(os.path.join(RESULTS_FOLDER, "multiscale_harris", category)): + os.makedirs(os.path.join(RESULTS_FOLDER, "multiscale_harris", category)) + show_detection(video, harris_points, + save_path=os.path.join(RESULTS_FOLDER, "multiscale_harris", category)) diff --git a/lab2/final/part2/test_names.txt b/lab2/final/part2/test_names.txt new file mode 100644 index 0000000..c4db253 --- /dev/null +++ b/lab2/final/part2/test_names.txt @@ -0,0 +1,15 @@ +SpatioTemporal/walking/person20_walking_d3_uncomp.avi +SpatioTemporal/running/person25_running_d4_uncomp.avi +SpatioTemporal/handwaving/person25_handwaving_d1_uncomp.avi +SpatioTemporal/walking/person13_walking_d3_uncomp.avi +SpatioTemporal/handwaving/person23_handwaving_d3_uncomp.avi +SpatioTemporal/handwaving/person04_handwaving_d1_uncomp.avi +SpatioTemporal/running/person05_running_d1_uncomp.avi +SpatioTemporal/handwaving/person06_handwaving_d1_uncomp.avi +SpatioTemporal/handwaving/person03_handwaving_d4_uncomp.avi +SpatioTemporal/running/person10_running_d2_uncomp.avi +SpatioTemporal/walking/person05_walking_d2_uncomp.avi +SpatioTemporal/handwaving/person21_handwaving_d1_uncomp.avi +SpatioTemporal/walking/person11_walking_d1_uncomp.avi +SpatioTemporal/handwaving/person09_handwaving_d4_uncomp.avi +SpatioTemporal/running/person03_running_d3_uncomp.avi \ No newline at end of file diff --git a/lab2/final/part2/train_names.txt b/lab2/final/part2/train_names.txt new file mode 100644 index 0000000..0231863 --- /dev/null +++ b/lab2/final/part2/train_names.txt @@ -0,0 +1,33 @@ +SpatioTemporal/handwaving/person05_handwaving_d2_uncomp.avi +SpatioTemporal/running/person20_running_d1_uncomp.avi +SpatioTemporal/handwaving/person22_handwaving_d2_uncomp.avi +SpatioTemporal/walking/person16_walking_d2_uncomp.avi +SpatioTemporal/running/person06_running_d3_uncomp.avi +SpatioTemporal/running/person01_running_d1_uncomp.avi +SpatioTemporal/running/person02_running_d2_uncomp.avi +SpatioTemporal/handwaving/person11_handwaving_d2_uncomp.avi +SpatioTemporal/handwaving/person15_handwaving_d4_uncomp.avi +SpatioTemporal/walking/person06_walking_d3_uncomp.avi +SpatioTemporal/running/person08_running_d4_uncomp.avi +SpatioTemporal/walking/person08_walking_d2_uncomp.avi +SpatioTemporal/handwaving/person24_handwaving_d4_uncomp.avi +SpatioTemporal/handwaving/person12_handwaving_d3_uncomp.avi +SpatioTemporal/running/person09_running_d1_uncomp.avi +SpatioTemporal/walking/person04_walking_d1_uncomp.avi +SpatioTemporal/walking/person14_walking_d4_uncomp.avi +SpatioTemporal/walking/person07_walking_d4_uncomp.avi +SpatioTemporal/running/person23_running_d2_uncomp.avi +SpatioTemporal/running/person24_running_d3_uncomp.avi +SpatioTemporal/walking/person18_walking_d4_uncomp.avi +SpatioTemporal/walking/person25_walking_d4_uncomp.avi +SpatioTemporal/walking/person19_walking_d1_uncomp.avi +SpatioTemporal/walking/person17_walking_d3_uncomp.avi +SpatioTemporal/handwaving/person01_handwaving_d2_uncomp.avi +SpatioTemporal/walking/person15_walking_d1_uncomp.avi +SpatioTemporal/running/person06_running_d2_uncomp.avi +SpatioTemporal/running/person21_running_d4_uncomp.avi +SpatioTemporal/handwaving/person02_handwaving_d3_uncomp.avi +SpatioTemporal/walking/person12_walking_d2_uncomp.avi +SpatioTemporal/running/person04_running_d4_uncomp.avi +SpatioTemporal/handwaving/person07_handwaving_d3_uncomp.avi +SpatioTemporal/running/person07_running_d3_uncomp.avi \ No newline at end of file diff --git a/lab2/final/part3/ImageStitching/img1_ratio01.jpg b/lab2/final/part3/ImageStitching/img1_ratio01.jpg new file mode 100644 index 0000000..9884f75 Binary files /dev/null and b/lab2/final/part3/ImageStitching/img1_ratio01.jpg differ diff --git a/lab2/final/part3/ImageStitching/img2_ratio01.jpg b/lab2/final/part3/ImageStitching/img2_ratio01.jpg new file mode 100644 index 0000000..371b267 Binary files /dev/null and b/lab2/final/part3/ImageStitching/img2_ratio01.jpg differ diff --git a/lab2/final/part3/ImageStitching/img3_ratio01.jpg b/lab2/final/part3/ImageStitching/img3_ratio01.jpg new file mode 100644 index 0000000..c98b87c Binary files /dev/null and b/lab2/final/part3/ImageStitching/img3_ratio01.jpg differ diff --git a/lab2/final/part3/ImageStitching/img4_ratio01.jpg b/lab2/final/part3/ImageStitching/img4_ratio01.jpg new file mode 100644 index 0000000..16ee27c Binary files /dev/null and b/lab2/final/part3/ImageStitching/img4_ratio01.jpg differ diff --git a/lab2/final/part3/ImageStitching/img5_ratio01.jpg b/lab2/final/part3/ImageStitching/img5_ratio01.jpg new file mode 100644 index 0000000..4dac059 Binary files /dev/null and b/lab2/final/part3/ImageStitching/img5_ratio01.jpg differ diff --git a/lab2/final/part3/ImageStitching/img6_ratio01.jpg b/lab2/final/part3/ImageStitching/img6_ratio01.jpg new file mode 100644 index 0000000..0fcc146 Binary files /dev/null and b/lab2/final/part3/ImageStitching/img6_ratio01.jpg differ diff --git a/lab2/final/part3/stitching.py b/lab2/final/part3/stitching.py new file mode 100644 index 0000000..5ac9d17 --- /dev/null +++ b/lab2/final/part3/stitching.py @@ -0,0 +1,27 @@ +import os +import cv2 +import matplotlib.pyplot as plt +from stitching_utils import stitchImages + + +IMAGE_PATH = 'ImageStitching' +IMAGE_NAME = 'img{num}_ratio01.jpg' +RESULT_PATH = 'StitchingResults' +RESULT_NAME = 'img{num1}_{num2}_stitched.jpg' +NUM_IMAGES = 6 + +START = False + +def main(): + # check if result path exists + if not os.path.exists(RESULT_PATH): + os.makedirs(RESULT_PATH) + for i in range(1, NUM_IMAGES): + img1 = cv2.imread(IMAGE_PATH + '/' + IMAGE_NAME.format(num=i)) + img2 = cv2.imread(IMAGE_PATH + '/' + IMAGE_NAME.format(num=i+1)) + stitched_img = stitchImages(img1, img2, match='bf') + cv2.imwrite(RESULT_PATH + '/' + RESULT_NAME.format(num1=i, num2=i+1), stitched_img) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/lab2/final/part3/stitching_utils.py b/lab2/final/part3/stitching_utils.py new file mode 100644 index 0000000..0999515 --- /dev/null +++ b/lab2/final/part3/stitching_utils.py @@ -0,0 +1,87 @@ +import cv2 +import numpy as np + +def combine_images(img1, img2, H): + """ + Combine two images together. + + Keyword arguments: + img1 -- first image + img2 -- second image + H -- homography matrix + """ + points1 = np.array([[0, 0], [0, img1.shape[0]], [img1.shape[1], img1.shape[0]], [img1.shape[1], 0]], dtype=np.float32) + points1 = points1.reshape((-1, 1, 2)) + + points2 = np.array([[0, 0], [0, img2.shape[0]], [img2.shape[1], img2.shape[0]], [img2.shape[1], 0]], dtype=np.float32) + points2 = points2.reshape((-1, 1, 2)) + + warped_points1 = cv2.perspectiveTransform(points1, H)[0] + warped_points1 = warped_points1.astype(np.int32) + warped_points1 = warped_points1.reshape((-1, 1, 2)) + + points = np.concatenate((points2, warped_points1), axis=0) + + [x_min, y_min] = np.min(points, axis=0).ravel().astype(np.int32) + [x_max, y_max] = np.max(points, axis=0).ravel().astype(np.int32) + + T = np.array([[1, 0, -x_min], [0, 1, -y_min], [0, 0, 1]], dtype=np.float32) + + output = cv2.warpPerspective(img1, T.dot(H), (x_max-x_min, y_max-y_min)) + output[-y_min:img2.shape[0]-y_min, -x_min:img2.shape[1]-x_min] = img2 + + return output + + +def stitchImages(img1, img2, match = 'bf'): + """ + Stitch two images together. + + Keyword arguments: + img1 -- first image + img2 -- second image + """ + + # Step1: Extract SIFT features and descriptors from both images + sift1 = cv2.xfeatures2d.SIFT_create() + sift2 = cv2.xfeatures2d.SIFT_create() + keypoints1, descriptors1 = sift1.detectAndCompute(img1, None) + keypoints2, descriptors2 = sift2.detectAndCompute(img2, None) + # Convert keypoints to numpy arrays + points1 = np.float32([kp.pt for kp in keypoints1]).reshape(-1, 1, 2) + points2 = np.float32([kp.pt for kp in keypoints2]).reshape(-1, 1, 2) + + # Step2: Match features by applying Brute-Force-based or FLANN-based matching + k = 2 + if match == 'bf': + bf = cv2.BFMatcher() + matches = bf.knnMatch(descriptors1, descriptors2, k) + elif match == 'flann': + index_params = dict(algorithm=0, trees=5) + search_params = dict(checks=50) + flann = cv2.FlannBasedMatcher(index_params, search_params) + matches = flann.knnMatch(descriptors1, descriptors2, k) + + # Step3: Apply Lowe's criterion to speedily reject most outliers + good = [] + for m, n in matches: + if m.distance < 0.7 * n.distance: + good.append(m) + matches = good + + points1 = np.float32([points1[m.queryIdx] for m in matches]).reshape(-1, 1, 2) + points2 = np.float32([points2[m.trainIdx] for m in matches]).reshape(-1, 1, 2) + + # Step4: Compute RANSAC-based Homography H + # given the matches between image 1 and image 2 + # we compute the homography H21 that maps + # points from image 1 to image 2 + # x2 = H21 * x1 + H = cv2.findHomography(points1, points2, cv2.RANSAC, 5.0)[0] + + # Step5: Apply inverse warping to img1 + + # Step6: Merge the warped version of img1 with img2 under the same coordinate system of img2 + stiched_img = combine_images(img1, img2, H) + + return stiched_img \ No newline at end of file diff --git a/lab2/part1/gifs/flow.gif b/lab2/part1/gifs/flow.gif new file mode 100644 index 0000000..d459a6d Binary files /dev/null and b/lab2/part1/gifs/flow.gif differ diff --git a/lab2/part1/gifs/flow_multiscale.gif b/lab2/part1/gifs/flow_multiscale.gif new file mode 100644 index 0000000..0170ac4 Binary files /dev/null and b/lab2/part1/gifs/flow_multiscale.gif differ diff --git a/lab2/part1/part1-GreekSignLanguage/skinSamplesRGB.mat b/lab2/part1/part1-GreekSignLanguage/skinSamplesRGB.mat new file mode 100644 index 0000000..e385b44 Binary files /dev/null and b/lab2/part1/part1-GreekSignLanguage/skinSamplesRGB.mat differ diff --git a/lab2/part1/ready_implementation.py b/lab2/part1/ready_implementation.py new file mode 100644 index 0000000..274418b --- /dev/null +++ b/lab2/part1/ready_implementation.py @@ -0,0 +1,92 @@ +from tracking_utils import lk +from tracking_utils import displ +from tracking_utils import makegif +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import numpy as np +import scipy.io +import cv2 + +NUM_IMAGES = 70 +STEP = 1 +AWESOME = False + +if __name__ == "__main__": + feats = 20 + padding = 20 + names = ["face", "right hand", "left hand"] + original = cv2.imread("part1-GreekSignLanguage/1.png") + initial = cv2.cvtColor(original, cv2.COLOR_BGR2YCR_CB) + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + mu, cov = FitSkinGaussian(skin_samples) + boundaries = fd(initial, mu, cov) + # find good features to track from the first image + # in each boundary + gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) + colours = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] + print(f"image.shape: {gray.shape}") + print(f"face: {boundaries[0]}") + print(f"right hand: {boundaries[1]}") + print(f"left hand: {boundaries[2]}") + dx0, dy0 = np.zeros(feats), np.zeros(feats) + for i in range(1, NUM_IMAGES): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image1 = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + image2 = cv2.imread(f"part1-GreekSignLanguage/{i+1}.png") + image_plot = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB) + gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) + gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) + + if AWESOME: + fig, axs = plt.subplots(2, 3) + axindices = {0: (0, 1), 1: (1, 2), 2: (1, 0)} + for j in range(2): + for k in range(3): + if (j, k) not in axindices.values(): + axs[j, k].axis("off") + for index, boundary in enumerate(boundaries): + y, x, h, w = boundary + # crop the image to retain only the pixels + # inside of the boundaries + cropped1 = gray1[y-padding:y+h+padding, x-padding:x+w+padding] + cropped2 = gray2[y-padding:y+h+padding, x-padding:x+w+padding] + features = np.squeeze(cv2.goodFeaturesToTrack(cropped2, feats, 0.05, 5).astype(int)) + [dx, dy] = lk(cropped1, cropped2, features, 2, 0.01, dx0, dy0) + + # compute the flow using the opencv method tv-l1 + + optical_flow = cv2.DualTVL1OpticalFlow_create() + flow = optical_flow.calc(cropped1, cropped2, None) + flowx = flow[:, :, 0] + flowy = flow[:, :, 1] + + + # update the boundaries + x = int(round(x - flowx)) + y = int(round(y - flowy)) + boundaries[index] = (y, x, h, w) + + # show the new boundaries + cv2.rectangle(image_plot, (x, y), (x + w, y + h), colours[index], 2) + + # plot the flow like a gradient field + if AWESOME: + axs[axindices[index]].quiver(features[:, 0], features[:, 1], -dx, -dy, angles='xy') + axs[axindices[index]].set_title(f"Optical flow for {names[index]}") + + if AWESOME: + axs[1, 1].imshow(image_plot) + axs[1, 1].set_title(f"Frame {i+1}") + else: + plt.imshow(image_plot) + plt.title(f"Frame {i+1}") + plt.tight_layout() + # show the image + plt.show() + # makegif("flow/", "flow.gif") + + diff --git a/lab2/part1/skin_detection.py b/lab2/part1/skin_detection.py new file mode 100644 index 0000000..391f6ef --- /dev/null +++ b/lab2/part1/skin_detection.py @@ -0,0 +1,47 @@ +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import scipy.io +import cv2 +import os + +NUM_IMAGES = 2 + +if __name__ == "__main__": + # load the skin samples that are stored in the + # same folder in .mat format in order to fit + # a gaussian curve on them. + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + # first convert the rgb values to ycbcr + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + # fit a gaussian curve on the skin samples + mu, cov = FitSkinGaussian(skin_samples) + print(f"Mean: {mu}") + print(f"Covariance: {cov}") + for i in range(1, 40, 5): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + + # convert the image to YCbCr color space + image_ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) + image_plot = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + boundaries = fd(image_ycrcb, mu, cov) + # draw the bounding boxes on the image + for boundary in boundaries: + # x, y, w, h = boundary + y, x, h, w = boundary + # cv2.rectangle(image, (y, x), (y+h, x+w), (0, 0, 255), 2) + cv2.rectangle(image_plot, (x, y), (x+w, y+h), (0, 255, 255), 2) + # show the image + fig, axs = plt.subplots(1, 1) + axs.imshow(image_plot) + axs.set_title(f"Skin detection on frame {i}") + # check if the results folder exists + # if not, create it + if not os.path.exists("results"): + os.makedirs("results") + plt.savefig(f"results/skin_detection_{i}.png") + + \ No newline at end of file diff --git a/lab2/part1/skin_detection_utils.py b/lab2/part1/skin_detection_utils.py new file mode 100644 index 0000000..0973444 --- /dev/null +++ b/lab2/part1/skin_detection_utils.py @@ -0,0 +1,83 @@ +import cv2 +import os +import numpy as np +from scipy import stats +from scipy import ndimage +import matplotlib.pyplot as plt + +SKIN_THRESHOLD = 0.05 + +def FitSkinGaussian(ycbcr_image): + """ Return mean and covariance of interest points' gaussian distribution + + Keyword arguments: + ycbcr_image -- input image in ycbcr color space. + """ + cbcr_image = ycbcr_image[:, :, 1:3] + height, width, channels = cbcr_image.shape + # calculate the average of cb and cr channels + mu = np.mean(cbcr_image.reshape(height*width, channels), axis=0) + # calculate the covariance of cb and cr channels + cov = np.cov(cbcr_image.reshape(height*width, channels).T) + return (mu, cov) + +def fd(image, mean, covariance): + """ Return bounding box of area of interest. + + Keyword arguments: + image -- the YCbCr input image. + mean -- the mean value of the gaussian distribution. + covariance -- the covariance of the gaussian distribution. + """ + # define the gaussian distribution according to the mean and covariance + distribution = stats.multivariate_normal(mean, covariance) + + # dstack means depth stack + # we give the Cb channel and the Cr channel + # and it forms an array of vectors (Cb, Cr) + pixels = np.dstack((image[:,:,1], image[:,:,2])) + # for the thresholding to work, it seems to be necessary to + # normalize the probability. i'm not sure why. + skin_image = (distribution.pdf(pixels)/np.max(distribution.pdf(pixels)) >= SKIN_THRESHOLD).astype('uint8') + + # save the binary skin image + plt.imshow(skin_image) + plt.title("Binary skin image before morphological operations") + # check if the results folder exists + # if not, create it + if not os.path.exists("results"): + os.makedirs("results") + plt.savefig("results/binary_skin_image.png") + + + # the skin image probably has holes + # we will attempt to close them by performing + # the opening with a small structural element and + # the closing with a bigger structural element + opening_strel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) + closing_strel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (19, 19)) + skin_image = cv2.morphologyEx(skin_image, cv2.MORPH_OPEN, opening_strel) + skin_image = cv2.morphologyEx(skin_image, cv2.MORPH_CLOSE, closing_strel) + + # save the binary skin image + plt.imshow(skin_image) + plt.title("Binary skin image after morphological operations") + plt.savefig("results/binary_skin_image_better.png") + # close the figure + plt.close() + + # find the connected components + # and return the bounding boxes of the + # connected components + labels, features = ndimage.label(skin_image) + boundaries = [] + for label in range(1, features+1): + # find the bounding box of the feature + # and append it to the list of boundaries + indices = np.where(labels == label) + y, x = indices[0], indices[1] + boundaries.append((np.min(y), np.min(x), np.max(y)-np.min(y), np.max(x)-np.min(x))) + return boundaries + + + diff --git a/lab2/part1/temp.py b/lab2/part1/temp.py new file mode 100644 index 0000000..a5232c8 --- /dev/null +++ b/lab2/part1/temp.py @@ -0,0 +1,229 @@ +def displ(dx, dy, method): + """ Display the optical flow + + Keyword arguments: + dx -- displacement x axis + dy -- displacement y axis + method -- method to display the optical flow + + returns -- optical flow for visualization + """ + + # In order to achieve a better visualization of the + # optical flow or to reject outliers, we could implement + # different techniques such as: + # - Computing the mean value of the displacement vectors + # that have greater energy than a certain threshold. + + if method == "energy": + # compute the energy of the optical flow + energies = np.array([np.sqrt(x**2 + y**2) for x, y in zip(dx, dy)]) + + # compute the mean value of the energy + mean_energy = np.mean(energies) + + # compute the threshold + threshold = 0.8*mean_energy + + # compute the indices of the optical flow + indices = np.where(energies <= threshold) + disp_x, disp_y = np.zeros(dx.shape), np.zeros(dy.shape) + disp_x[indices], disp_y[indices] = dx[indices], dy[indices] + return np.array([np.mean(disp_x), np.mean(disp_y)]) + elif method == "texture": + # It is known that the optical flow vectors + # tend to have greatest norm at points that + # belong to the areas of high textural information + # and low norm at points that belong to the areas + # of low textural information and uniform texture. + # Therefore, since the majority of interest points + # are located in areas of high textural information, + # we could simply use the mean value of the displacement + # vectors. + return np.array([np.mean(dx), np.mean(dy)]) + else: + print("Method has to be either 'energy' or 'texture'.") + exit(5) + + + +def displ(dx, dy, method): + """ Display the optical flow + + Keyword arguments: + dx -- displacement x axis + dy -- displacement y axis + method -- method to display the optical flow + + returns -- optical flow for visualization + """ + + # In order to achieve a better visualization of the + # optical flow or to reject outliers, we could implement + # different techniques such as: + # - Computing the mean value of the displacement vectors + # that have greater energy than a certain threshold. + + if method == "energy": + # compute the energy of the optical flow + energies = np.array([np.sqrt(x**2 + y**2) for x, y in zip(dx, dy)]) + + # compute the mean value of the energy + mean_energy = np.mean(energies) + + # compute the threshold + threshold = 0.8*mean_energy + + # compute the indices of the optical flow + indices = np.where(energies <= threshold) + disp_x, disp_y = np.zeros(dx.shape), np.zeros(dy.shape) + disp_x[indices], disp_y[indices] = dx[indices], dy[indices] + return np.array([np.mean(disp_x), np.mean(disp_y)]) + elif method == "texture": + # It is known that the optical flow vectors + # tend to have greatest norm at points that + # belong to the areas of high textural information + # and low norm at points that belong to the areas + # of low textural information and uniform texture. + # Therefore, since the majority of interest points + # are located in areas of high textural information, + # we could simply use the mean value of the displacement + # vectors. + return np.array([np.mean(dx), np.mean(dy)]) + else: + print("Method has to be either 'energy' or 'texture'.") + exit(5) + + +def lk(i1, i2, features, rho, epsilon, dx0, dy0): + """ + Lucas-Kanade algorithm + + Arguments: + i1 -- initial frame + i2 -- next frame + features -- coordinates of interest-points + rho -- Gaussian width parameter + epsilon -- minimum constant to avoid zeroes + dx0 -- initial condition x-axis + dy0 -- initial condition y-axis + + Returns: + dx -- computed displacement along x-axis + dy -- computed displacement along y-axis + """ + + # Calculate gradient of the initial frame + gradient_x = np.gradient(i1, axis=1) + gradient_y = np.gradient(i1, axis=0) + + dx = dx0 + dy = dy0 + + # Iterative refinement + while True: + # Warp the second frame using the current displacement estimates + warped_i2 = np.zeros_like(i2) + for idx, (x, y) in enumerate(features): + x = int(x) + y = int(y) + warped_i2[y, x] = i2[y + int(dy[idx]), x + int(dx[idx])] + + # Calculate the error between the initial and warped frames + error = i1 - warped_i2 + + # Compute the Lucas-Kanade equations + A = np.zeros((len(features), 2, 2)) + b = np.zeros((len(features), 2)) + + for idx, (x, y) in enumerate(features): + x = int(x) + y = int(y) + + A[idx, 0, 0] = np.sum(gradient_x[y, x]**2) + A[idx, 0, 1] = np.sum(gradient_x[y, x] * gradient_y[y, x]) + A[idx, 1, 0] = np.sum(gradient_x[y, x] * gradient_y[y, x]) + A[idx, 1, 1] = np.sum(gradient_y[y, x]**2) + + b[idx, 0] = np.sum(gradient_x[y, x] * error[y, x]) + b[idx, 1] = np.sum(gradient_y[y, x] * error[y, x]) + + # Solve the linear equations using least squares + try: + deltas = np.linalg.solve(A, b) + except np.linalg.LinAlgError: + break + + delta_x = deltas[:, 0] + delta_y = deltas[:, 1] + + # Update the displacement estimates + dx += delta_x + dy += delta_y + + # Check convergence + if np.max(np.abs(delta_x)) < epsilon and np.max(np.abs(delta_y)) < epsilon: + break + + return dx, dy + +#system = np.array([[filter2D(gradx**2, -1, kernel, borderType=1)[x,y] + epsilon, +# filter2D(gradx*grady, -1, kernel, borderType=1)[x,y]], +# [filter2D(gradx*grady, -1, kernel, borderType=1)[x,y], +# filter2D(grady**2, -1, kernel, borderType=1)[x,y] + epsilon]]) +#steps = np.array([filter2D(gradx*error, -1, kernel, borderType=1)[x,y], +# filter2D(grady*error, -1, kernel, borderType=1)[x,y]]) + +# +# returnx, returny = np.zeros(len(features)), np.zeros(len(features)) +# +# grady, gradx = np.gradient(i1) +# s11 = filter2D(gradx**2, -1, kernel, borderType=1) + epsilon +# s12 = filter2D(gradx*grady, -1, kernel, borderType=1) +# s22 = filter2D(grady**2, -1, kernel, borderType=1) + epsilon +# +# for index, feature in enumerate(features): +# # define a small area around the feature +# x, y = int(feature[0]), int(feature[1]) +# original = i1[x-2:x+2, y-2:y+2] +# following = i2[x-2:x+2, y-2:y+2] +# # use the initial guess for the optical flow +# # of the current feature +# dx, dy = dx0[index], dy0[index] +# +# +# while (iterations < limit and change > threshold): +# # compute the shifted image of the first frame +# initial = shift_image(original, [dx, dy]) +# print(f"dx: {dx}, dy: {dy}") +# print(f"initial shape: {initial.shape}") +# # compute the error between the second frame +# # and the shifted first frame +# error = following - initial +# +# # compute the shifted image of the gradient +# a1 = shift_image(gradx[x-2:x+2, y-2:y+2], [dx, dy]) +# a2 = shift_image(grady[x-2:x+2, y-2:y+2], [dx, dy]) +# print(f"gradx shape: {gradx.shape}") +# print(f"grady shape: {grady.shape}") +# +# b1 = filter2D(a1*error, -1, kernel, borderType=1) +# b2 = filter2D(a2*error, -1, kernel, borderType=1) +# +# # setup the matrices to calculate the improvement +# system = np.array([[s11[x,y], s12[x,y]], +# [s12[x,y], s22[x,y]]]) +# steps = np.array([b1[x,y], b2[x,y]]) +# # calculate the improvement +# det = system[0, 0]*system[1, 1] - system[0, 1]*system[1, 0] +# imp_x = (system[1, 1]*steps[0] - system[0, 1]*steps[1])/det +# imp_y = (system[0, 0]*steps[1] - system[1, 0]*steps[0])/det +# improvement = np.array([imp_x, imp_y]) +# # update the parameters +# dx, dy = dx + improvement[0], dy + improvement[1] +# # calculate the change +# change = np.linalg.norm(improvement) +# # update the iterations +# iterations += 1 +# returnx[index], returny[index] = dx, dy +# \ No newline at end of file diff --git a/lab2/part1/tracking.py b/lab2/part1/tracking.py new file mode 100644 index 0000000..53c99bd --- /dev/null +++ b/lab2/part1/tracking.py @@ -0,0 +1,87 @@ +from tracking_utils import lk +from tracking_utils import displ +from tracking_utils import makegif +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import numpy as np +import scipy.io +import cv2 + +NUM_IMAGES = 70 +STEP = 1 +AWESOME = False + +if __name__ == "__main__": + feats = 20 + padding = 20 + names = ["face", "right hand", "left hand"] + original = cv2.imread("part1-GreekSignLanguage/1.png") + initial = cv2.cvtColor(original, cv2.COLOR_BGR2YCR_CB) + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + mu, cov = FitSkinGaussian(skin_samples) + boundaries = fd(initial, mu, cov) + # find good features to track from the first image + # in each boundary + gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) + colours = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] + print(f"image.shape: {gray.shape}") + print(f"face: {boundaries[0]}") + print(f"right hand: {boundaries[1]}") + print(f"left hand: {boundaries[2]}") + dx0, dy0 = np.zeros(feats), np.zeros(feats) + for i in range(1, NUM_IMAGES): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image1 = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + image2 = cv2.imread(f"part1-GreekSignLanguage/{i+1}.png") + image_plot = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB) + gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) + gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) + + if AWESOME: + fig, axs = plt.subplots(2, 3) + axindices = {0: (0, 1), 1: (1, 2), 2: (1, 0)} + for j in range(2): + for k in range(3): + if (j, k) not in axindices.values(): + axs[j, k].axis("off") + for index, boundary in enumerate(boundaries): + y, x, h, w = boundary + # crop the image to retain only the pixels + # inside of the boundaries + cropped1 = gray1[y-padding:y+h+padding, x-padding:x+w+padding] + cropped2 = gray2[y-padding:y+h+padding, x-padding:x+w+padding] + features = np.squeeze(cv2.goodFeaturesToTrack(cropped2, feats, 0.05, 5).astype(int)) + [dx, dy] = lk(cropped1, cropped2, features, 2, 0.01, dx0, dy0) + + # compute the flow + [flowx, flowy] = displ(dx, dy, 0.7) + + # update the boundaries + x = int(round(x - flowx)) + y = int(round(y - flowy)) + boundaries[index] = (y, x, h, w) + + # show the new boundaries + cv2.rectangle(image_plot, (x, y), (x + w, y + h), colours[index], 2) + + # plot the flow like a gradient field + if AWESOME: + axs[axindices[index]].quiver(features[:, 0], features[:, 1], -dx, -dy, angles='xy') + axs[axindices[index]].set_title(f"Optical flow for {names[index]}") + + if AWESOME: + axs[1, 1].imshow(image_plot) + axs[1, 1].set_title(f"Frame {i+1}") + else: + plt.imshow(image_plot) + plt.title(f"Frame {i+1}") + plt.tight_layout() + # save the figure + plt.savefig(f"flow/n_{i+1}.png") + # makegif("flow/", "flow.gif") + + diff --git a/lab2/part1/tracking_multiscale.py b/lab2/part1/tracking_multiscale.py new file mode 100644 index 0000000..b896d83 --- /dev/null +++ b/lab2/part1/tracking_multiscale.py @@ -0,0 +1,86 @@ +from tracking_utils import multiscale_lk +from tracking_utils import displ +from tracking_utils import makegif +from skin_detection_utils import FitSkinGaussian +from skin_detection_utils import fd +import matplotlib.pyplot as plt +import numpy as np +import scipy.io +import cv2 + +AWESOME = False + +if __name__ == "__main__": + feats = 20 + padding = 20 + scales = 3 + names = ["face", "right hand", "left hand"] + original = cv2.imread("part1-GreekSignLanguage/1.png") + initial = cv2.cvtColor(original, cv2.COLOR_BGR2YCR_CB) + skin_samples = scipy.io.loadmat("part1-GreekSignLanguage/skinSamplesRGB.mat") + skin_samples = skin_samples["skinSamplesRGB"] + skin_samples = cv2.cvtColor(skin_samples, cv2.COLOR_RGB2YCR_CB) + mu, cov = FitSkinGaussian(skin_samples) + boundaries = fd(initial, mu, cov) + # find good features to track from the first image + # in each boundary + gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) + colours = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] + print(f"image.shape: {gray.shape}") + boundaries = fd(initial, mu, cov) + print(f"face: {boundaries[0]}") + print(f"right hand: {boundaries[1]}") + print(f"left hand: {boundaries[2]}") + dx0, dy0 = np.zeros(feats), np.zeros(feats) + for i in range(1, 69): + # load some image from the dataset in + # the "part1-GreekSignLanguage" folder. + image1 = cv2.imread(f"part1-GreekSignLanguage/{i}.png") + image2 = cv2.imread(f"part1-GreekSignLanguage/{i+1}.png") + image_plot = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB) + gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) + gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) + + if AWESOME: + fig, axs = plt.subplots(2, 3) + axindices = {0: (0, 1), 1: (1, 2), 2: (1, 0)} + for j in range(2): + for k in range(3): + if (j, k) not in axindices.values(): + axs[j, k].axis("off") + for index, boundary in enumerate(boundaries): + y, x, h, w = boundary + # crop the image to retain only the pixels + # inside of the boundaries + cropped1 = gray1[y-padding:y+h+padding, x-padding:x+w+padding] + cropped2 = gray2[y-padding:y+h+padding, x-padding:x+w+padding] + [dx, dy] = multiscale_lk(cropped1, cropped2, feats, 2, 0.01, scales) + + # compute the flow + [flowx, flowy] = displ(dx, dy, 0.7) + + # update the boundaries + x = int(round(x - flowx)) + y = int(round(y - flowy)) + boundaries[index] = (y, x, h, w) + + # show the new boundaries + cv2.rectangle(image_plot, (x, y), (x + w, y + h), colours[index], 2) + + # plot the flow like a gradient field + if AWESOME: + features = np.squeeze(cv2.goodFeaturesToTrack(cropped2, feats, 0.05, 5).astype(int)) + axs[axindices[index]].quiver(features[:, 0], features[:, 1], -dx, -dy, angles='xy') + axs[axindices[index]].set_title(f"Optical flow for {names[index]}") + if AWESOME: + axs[1, 1].imshow(image_plot) + axs[1, 1].set_title(f"Frame {i}") + else: + plt.imshow(image_plot) + plt.title(f"Frame {i}") + plt.tight_layout() + # save the figure + plt.savefig(f"flow_multiscale/n_{i}.png") + # makegif("flow_multiscale/", "flow_multiscale.gif") + + diff --git a/lab2/part1/tracking_utils.py b/lab2/part1/tracking_utils.py new file mode 100644 index 0000000..1b7fad9 --- /dev/null +++ b/lab2/part1/tracking_utils.py @@ -0,0 +1,193 @@ +import numpy as np +import imageio +import cv2 +from scipy.ndimage import map_coordinates + +def lk(i1, i2, features, rho, epsilon, dx0, dy0): + """ Lucas-Kanade algorithm + + Keyword arguments: + i1 -- initial frame + i2 -- next frame + features -- coordinates of interest-points + rho -- gaussian width parameter + epsilon -- minimum constant to avoid zeroes + dx0 -- initial guesses for movement of features in x axis + dy0 -- initial guesses for movement of features in y axis + returns -- [dx, dy] actual estimates for movement of features + """ + # first define a helper function that + # accomodated the shifting of images + def shift_image(image, shift): + """ Shift the image + + Keyword arguments: + image -- image to be shifted + shift -- shift amount + """ + dx, dy = shift + x, y = np.meshgrid(np.arange(image.shape[1]), np.arange(image.shape[0])) + return map_coordinates(image,[np.ravel(y + dy), np.ravel(x + dx)], order=1).reshape(image.shape) + + # convert the images to float in [0,1] + # for the parameters to make sense + i1 = i1.astype(np.float)/255 + i2 = i2.astype(np.float)/255 + # define limit of iterations + # and threshold of change + limit = 150 + threshold = 0.001 + # setup the kernel for the convolutions + # this kernel acts as a gaussian filter + size = int(2*np.ceil(3*rho)+1) + mid = (size-1)//2 + kernel = cv2.getGaussianKernel(size, rho) + kernel = kernel @ kernel.T + + # initialize result vectors + returnx = np.zeros(len(features)) + returny = np.zeros(len(features)) + + for index, feature in enumerate(features): + # get the coordinates of the feature + x, y = feature + # get area around the feature in both images + initial_image = i1[max(0, y-mid):min(y+mid, i1.shape[0]), + max(0, x-mid):min(x+mid, i1.shape[1])] + next_image = i2[max(0, y-mid):min(y+mid, i2.shape[0]), + max(0, x-mid):min(x+mid, i2.shape[1])] + # compute the gradient of the initial image + gradient_y, gradient_x = np.gradient(initial_image) + + # initialize iteration counter and change + iterations = 0 + change = float('inf') + dy, dx = dy0[index], dx0[index] + while (iterations < limit and change > threshold): + # shift the initial image by the current displacement + shifted_image = shift_image(initial_image, [dx, dy]) + # shift the gradient of the initial image by the current displacement + shifted_gradient_x = shift_image(gradient_x, [dx, dy]) + shifted_gradient_y = shift_image(gradient_y, [dx, dy]) + # compute the error between the shifted image and the next image + error = next_image - shifted_image + # compute the Lucas-Kanade equations + s11 = cv2.filter2D(shifted_gradient_x**2, -1, kernel)[mid,mid] + epsilon + s12 = cv2.filter2D(shifted_gradient_x*shifted_gradient_y, -1, kernel)[mid,mid] + s22 = cv2.filter2D(shifted_gradient_y**2, -1, kernel)[mid,mid] + epsilon + b1 = cv2.filter2D(shifted_gradient_x*error, -1, kernel)[mid,mid] + b2 = cv2.filter2D(shifted_gradient_y*error, -1, kernel)[mid,mid] + # compute the determinant of the system + det = s11*s22 - s12*s12 + # compute the improvement + delta_x = (s22*b1 - s12*b2)/det + delta_y = (s11*b2 - s12*b1)/det + # update the displacement estimates + dx += delta_x + dy += delta_y + # compute the change + change = np.linalg.norm([delta_x, delta_y]) + # update the number of iterations + iterations += 1 + # update the displacement estimates + returnx[index] = dx + returny[index] = dy + return np.array([returnx, returny]) + +def multiscale_lk(i1, i2, num_features, rho, epsilon, scale): + """ Multiscale Lucas-Kanade algorithm + + Keyword arguments: + i1 -- initial frame + i2 -- next frame + num_features -- number of features to track + rho -- gaussian width parameter + epsilon -- minimum constant to avoid zeroes + scale -- number of scales in the pyramid + returns -- [dx, dy] actual estimates for movement of features + """ + # first define some helper functions + # that do not need to be visible outside + # of this function + def pyramid(image, levels): + """ Create a pyramid of images + + Keyword arguments: + image -- image to be scaled + levels -- number of levels in the pyramid + """ + + def downscale(image): + """ Downscale the image by a factor of 2 + + Keyword arguments: + image -- image to be downscaled + """ + gauss = cv2.getGaussianKernel(3, 1) + gauss = gauss @ gauss.T + return cv2.filter2D(image, -1, gauss)[::2,::2] + + result = [image] + for i in range(levels - 1): + result.append(downscale(result[i])) + + result.reverse() + return result + + # we should normalize the images, + # but we do not need to do it here + # because we already do it in lk. + + # therefore, build the pyramids + # with the original images + # from deep level to shallow level. + pyramid1 = pyramid(i1, scale) + pyramid2 = pyramid(i2, scale) + + # initialize result vectors. + dx0, dy0 = np.zeros(num_features), np.zeros(num_features) + + for level in range(scale): + features = np.squeeze(cv2.goodFeaturesToTrack(pyramid2[level], num_features, 0.05, 5).astype(int)) + + [dx, dy] = lk(pyramid1[level], pyramid2[level], features, rho, epsilon, dx0, dy0) + [flowx, flowy] = displ(dx, dy, 0.7) + # update the initial guesses + if level < scale - 1: + dx0 = np.full((num_features), 2*flowx) + dy0 = np.full((num_features), 2*flowy) + + return np.array([dx, dy]) + +def displ(dx, dy, threshold): + """ Display the optical flow + + Keyword arguments: + dx -- displacement x axis + dy -- displacement y axis + threshold -- threshold for the optical flow + """ + energies = np.array([x**2 + y**2 for x, y in zip(dx, dy)]) + mean_energy = np.mean(energies) + energy = np.array([np.array([dx, dy]) + for x, y in zip(dx, dy) + if (x**2 + y**2) > threshold*mean_energy]) + + # check if there are any features + # with enough energy + if energy.shape[0] == 0: + return [0, 0] + return [np.mean(energy[:,0]), np.mean(energy[:,1])] + +def makegif(path, name): + images = [] + for i in range(1, 69): + print(path + str(i+1) + '.png') + img = cv2.imread(path + str(i+1) + '.png',1) + #check if image is empty + if img is None: + print('Image is empty') + return + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + images.append(img) + imageio.mimsave('gifs/'+name, images) \ No newline at end of file diff --git a/lab2/part2/.vscode/settings.json b/lab2/part2/.vscode/settings.json new file mode 100644 index 0000000..cad7657 --- /dev/null +++ b/lab2/part2/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/lab2/part2/classification.py b/lab2/part2/classification.py new file mode 100644 index 0000000..020c9b3 --- /dev/null +++ b/lab2/part2/classification.py @@ -0,0 +1,211 @@ +import os +import numpy as np +import random +import pickle +from itertools import product +from detector_utils import get_hog_hof, get_hof_descriptors, get_hog_descriptors, GaborDetector, HarrisDetector, MultiscaleDetector +from cv23_lab2_2_utils import bag_of_words, read_video, svm_train_test + +NBINS = 10 +NUM_FRAMES = 200 + +TRAIN_NAMES_FILE = "train_names.txt" +TEST_NAMES_FILE = "test_names.txt" + +VIDEO_FOLDER = "SpatioTemporal/{label}" + +# define dictionary for multiple tests +# each test is a dictionary with keys: +# scale, detector, descriptor, points + +PARAMETERS = { + "scale": ["multiscale"], + "detector": ["gabor", "harris"], + "descriptor": ["hog_hof", "hog", "hof"], + "points": [500] # if we want to test more points, we have to lower the thresholds. +} + +DESCRIPTORS_FILE = "classification_descriptors/{scale}_{detector}_{descriptor}_{points}.pickle" +RESULTS_FILE = "classification_results/{scale}_{detector}_{descriptor}_{points}.txt" + +def init_detectors(scale, detector): + """ + Returns the detector function. + + Keyword arguments: + scale -- the scale of the detector + detector -- the detector to use + """ + print("\n\tInitializing detector...") + if scale == "multiscale": + if detector == "harris": + detector = lambda video, points: MultiscaleDetector(lambda video, sigma, tau: + HarrisDetector(video, 2, sigma, tau, kappa=0.005, threshold=0.05, num_points=points), + video, [4*(1.1**i) for i in range(8)], tau=1.5, num_points=points) + elif detector == "gabor": + detector = lambda video, points: MultiscaleDetector(lambda video, sigma, tau: + GaborDetector(video, sigma, tau, threshold=0.1, num_points=points), + video, [4*(1.1**i) for i in range(8)], tau=1.5, num_points=points) + else: + raise ValueError("DETECTOR must be either 'harris' or 'gabor'") + elif scale == "uniscale": + if detector == "harris": + detector = lambda video, points: HarrisDetector(video, s=2, sigma=4, tau=1.5, + kappa=0.005, threshold=0.05, num_points=points) + elif detector == "gabor": + detector = lambda video, points: GaborDetector(video, sigma=4, tau=1.5, + threshold=0.25, num_points=points) + else: + raise ValueError("DETECTOR must be either 'harris' or 'gabor'") + print("\tFinished ...") + return detector + +def init_descriptors(descriptor): + """ + Returns the get_descriptors function. + + Keyword arguments: + descriptor -- the descriptor to use + """ + print("\n\tInitializing descriptor...") + if descriptor == "hog": + get_descriptors = lambda video, points: get_hog_descriptors(video, points, nbins=NBINS) + elif descriptor == "hof": + get_descriptors = lambda video, points: get_hof_descriptors(video, points, nbins=NBINS) + elif descriptor == "hog_hof": + get_descriptors = lambda video, points: get_hog_hof(video, points, nbins=NBINS) + else: + raise ValueError("DESCRIPTOR must be either 'hog', 'hof' or 'hog_hof'") + print("\tFinished ...") + return get_descriptors + +def get_names(): + """ + Returns the train and test names. + If train_names.txt and test_names.txt exist, + it loads them. + Otherwise, it creates them. + """ + print("\n\tGetting names...") + # check if train_names.txt and test_names.txt exist + # if they exist, load them: + if os.path.exists(TRAIN_NAMES_FILE) and os.path.exists(TEST_NAMES_FILE): + # read them + with open(TRAIN_NAMES_FILE, "r") as f: + train_names = f.read().splitlines() + with open(TEST_NAMES_FILE, "r") as f: + test_names = f.read().splitlines() + # otherwise, create them: + else: + # get all the video names with full path + # from current directory + video_names = [] + for label in ["handwaving", "running", "walking"]: + video_names += [os.path.join(VIDEO_FOLDER.format(label=label), video_name) + for video_name in os.listdir(VIDEO_FOLDER.format(label=label))] + + # shuffle them + random.shuffle(video_names) + + # split them into train and test + train_names = video_names[:int(0.7*len(video_names))] + test_names = video_names[int(0.7*len(video_names)):] + + # save them + with open(TRAIN_NAMES_FILE, "w") as f: + f.write("\n".join(train_names)) + with open(TEST_NAMES_FILE, "w") as f: + f.write("\n".join(test_names)) + print("\tFinished ...") + return train_names, test_names + +def extract_descriptors(names, detector, get_descriptors, points): + """ + Extracts the descriptors from the videos. + + Keyword arguments: + names -- the names of the videos + detector -- the detector to use + get_descriptors -- the descriptor to use + points -- the number of points to use + """ + print("\n\tExtracting descriptors...") + descriptors = [] + for name in names: + video = read_video(name, NUM_FRAMES, 0) + interest = detector(video, points) + descs = get_descriptors(video, interest) + descriptors.append(descs) + print("\tChecking if all descriptors have the same shape...") + original_shape = descriptors[0].shape + print(f"\toriginal_shape: {original_shape}") + for index, descriptor in enumerate(descriptors): + if descriptor.shape != original_shape: + raise ValueError(f"All descriptors must have the same shape. Descriptor {index} has shape {descriptor.shape}") + print("\tFinished ...") + return descriptors + +def run_test(scale, detector, descriptor, points): + """ + Runs the test for the current parameters. + + Saves the descriptors in a pickle file. + Saves the results in a text file. + + Keyword arguments: + scale -- the scale of the detector + detector -- the detector to use + descriptor -- the descriptor to use + points -- the number of points to use + """ + fun_detector = init_detectors(scale, detector) + get_descriptors = init_descriptors(descriptor) + train_names, test_names = get_names() + + # Define a dictionary for label mappings + label_mappings = { "handwaving": 0, "running": 1, "walking": 2 } + + # Generate test_labels + test_labels = [label_mappings[name.split("_")[1]] for name in test_names] + # Generate train_labels + train_labels = [label_mappings[name.split("_")[1]] for name in train_names] + + # check if descriptors have already been computed + if os.path.exists(DESCRIPTORS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points)): + print("\n\tLoading descriptors...") + with open(DESCRIPTORS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points), "rb") as f: + descriptors = pickle.load(f) + test_descriptors = descriptors["test"] + train_descriptors = descriptors["train"] + else: + # Extract descriptors + test_descriptors = extract_descriptors(test_names, fun_detector, get_descriptors, points) + train_descriptors = extract_descriptors(train_names, fun_detector, get_descriptors, points) + + # train and test + bow_train, bow_test = bag_of_words(train_descriptors, test_descriptors, num_centers=50) + accuracy, pred = svm_train_test(bow_train, train_labels, bow_test, test_labels) + with open(RESULTS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points), "w") as f: + f.write("Accuracy: {accuracy}\n".format(accuracy=accuracy)) + f.write("Predictions: {pred}\n".format(pred=pred)) + f.write("Test labels: {test_labels}\n".format(test_labels=test_labels)) + + with open(DESCRIPTORS_FILE.format(scale=scale, detector=detector, + descriptor=descriptor, points=points), "wb") as f: + pickle.dump({"test": test_descriptors, "train": train_descriptors}, f) + +def main(): + keys = PARAMETERS.keys() + combinations = product(*[PARAMETERS[key] for key in keys]) + for combination in combinations: + scale, detector, descriptor, points = combination + # run the test + print(f"Test: scale={scale}, detector={detector}, descriptor={descriptor}, points={points}") + run_test(scale, detector, descriptor, points) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/lab2/part2/classification_results/uniscale_gabor_hof_500.txt b/lab2/part2/classification_results/uniscale_gabor_hof_500.txt new file mode 100644 index 0000000..96e8b4b --- /dev/null +++ b/lab2/part2/classification_results/uniscale_gabor_hof_500.txt @@ -0,0 +1,3 @@ +Accuracy: 0.8 +Predictions: [2 1 0 2 0 0 2 0 0 0 1 0 2 0 1] +Test labels: [2, 1, 0, 2, 0, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1] diff --git a/lab2/part2/classification_results/uniscale_gabor_hog_500.txt b/lab2/part2/classification_results/uniscale_gabor_hog_500.txt new file mode 100644 index 0000000..8f55a88 --- /dev/null +++ b/lab2/part2/classification_results/uniscale_gabor_hog_500.txt @@ -0,0 +1,3 @@ +Accuracy: 1.0 +Predictions: [2 1 0 2 0 0 1 0 0 1 2 0 2 0 1] +Test labels: [2, 1, 0, 2, 0, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1] diff --git a/lab2/part2/classification_results/uniscale_gabor_hog_hof_500.txt b/lab2/part2/classification_results/uniscale_gabor_hog_hof_500.txt new file mode 100644 index 0000000..f552f63 --- /dev/null +++ b/lab2/part2/classification_results/uniscale_gabor_hog_hof_500.txt @@ -0,0 +1,3 @@ +Accuracy: 0.8 +Predictions: [2 1 0 0 0 0 1 0 0 0 1 0 2 0 1] +Test labels: [2, 1, 0, 2, 0, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1] diff --git a/lab2/part2/classification_results/uniscale_harris_hof_500.txt b/lab2/part2/classification_results/uniscale_harris_hof_500.txt new file mode 100644 index 0000000..2e16663 --- /dev/null +++ b/lab2/part2/classification_results/uniscale_harris_hof_500.txt @@ -0,0 +1,3 @@ +Accuracy: 0.6 +Predictions: [2 2 0 1 1 1 1 0 0 1 1 1 2 0 1] +Test labels: [2, 1, 0, 2, 0, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1] diff --git a/lab2/part2/classification_results/uniscale_harris_hog_500.txt b/lab2/part2/classification_results/uniscale_harris_hog_500.txt new file mode 100644 index 0000000..81b2cc8 --- /dev/null +++ b/lab2/part2/classification_results/uniscale_harris_hog_500.txt @@ -0,0 +1,3 @@ +Accuracy: 0.6666666666666666 +Predictions: [2 1 0 1 0 1 1 0 1 1 0 1 2 0 1] +Test labels: [2, 1, 0, 2, 0, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1] diff --git a/lab2/part2/classification_results/uniscale_harris_hog_hof_500.txt b/lab2/part2/classification_results/uniscale_harris_hog_hof_500.txt new file mode 100644 index 0000000..bab592b --- /dev/null +++ b/lab2/part2/classification_results/uniscale_harris_hog_hof_500.txt @@ -0,0 +1,3 @@ +Accuracy: 0.8666666666666667 +Predictions: [2 2 0 1 0 0 1 0 0 1 2 0 2 0 1] +Test labels: [2, 1, 0, 2, 0, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1] diff --git a/lab2/part2/cv23_lab2_2_utils.pyc b/lab2/part2/cv23_lab2_2_utils.pyc new file mode 100644 index 0000000..1703384 Binary files /dev/null and b/lab2/part2/cv23_lab2_2_utils.pyc differ diff --git a/lab2/part2/detector_utils.py b/lab2/part2/detector_utils.py new file mode 100644 index 0000000..b7398b7 --- /dev/null +++ b/lab2/part2/detector_utils.py @@ -0,0 +1,293 @@ +import cv2 +import numba +import numpy as np +import scipy.ndimage as scp +from cv23_lab2_2_utils import orientation_histogram + +def video_gradients(video): + """ + Compute the gradients of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) normalized to [0, 1] + """ + # compute gradients + Ly = scp.convolve1d(video, np.array([-1, 0, 1]), axis=0) + Lx = scp.convolve1d(video, np.array([-1, 0, 1]), axis=1) + Lt = scp.convolve1d(video, np.array([-1, 0, 1]), axis=2) + return Ly, Lx, Lt + +def video_smoothen(video, space_kernel, time_kernel): + """ + Smoothen a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) normalized to [0, 1] + space_kernel -- Gaussian kernel space standard deviation + time_kernel -- Gaussian kernel time standard deviation + """ + video = scp.convolve1d(video, space_kernel, axis=0) + video = scp.convolve1d(video, space_kernel, axis=1) + video = scp.convolve1d(video, time_kernel, axis=2) + return video + +def video_smoothen_space(video, sigma): + """ + Smoothen a video in space. + + Keyword arguments: + video -- input video (y_len, x_len, frames) normalized to [0, 1] + sigma -- Gaussian kernel space standard deviation + """ + # define Gaussian kernel + space_size = int(2*np.ceil(3*sigma)+1) + kernel = cv2.getGaussianKernel(space_size, sigma).T[0] + # smoothen the video + video = scp.convolve1d(video, kernel, axis=0) + video = scp.convolve1d(video, kernel, axis=1) + return video + +def interest_points(response, num, threshold, scale): + """ + Find interest points in a video. + + Keyword arguments: + response -- response (y_len, x_len, frames) + num -- number of interest points + threshold -- threshold + scale -- scale + """ + maxr = np.max(response.flatten()) + x, y, t = np.where(response > threshold*maxr) + points = np.column_stack((y, x, t, scale*np.ones(len(x)))) + + # Sort points based on response values in descending order + response_values = response[x, y, t] + sorted_indices = np.argsort(response_values)[::-1] # Sort in descending order + + # Select the top 'num' points + top_points = points[sorted_indices[:num]] + return top_points + +def HarrisDetector(v, s, sigma, tau, kappa, threshold, num_points): + """ + Harris Corner Detector + + Keyword arguments: + video -- input video (y_len, x_len, frames) + s -- Gaussian kernel size + sigma -- Gaussian kernel space standard deviation + tau -- Gaussian kernel time standard deviation + rho -- Harris response threshold + """ + # define Gaussian kernel + space_size = int(2*np.ceil(3*sigma)+1) + time_size = int(2*np.ceil(3*tau)+1) + space_kernel = cv2.getGaussianKernel(space_size, sigma).T[0] + time_kernel = cv2.getGaussianKernel(time_size, tau).T[0] + # setup video + video = v.copy() # copy so we don't modify the original + video = video.astype(float)/video.max() + video = video_smoothen(video, space_kernel, time_kernel) + # compute gradients + Ly, Lx, Lt = video_gradients(video) + # define Gaussian kernel + space_size = int(2*np.ceil(3*s*sigma)+1) + time_size = int(2*np.ceil(3*s*tau)+1) + space_kernel = cv2.getGaussianKernel(space_size, s*sigma).T[0] + time_kernel = cv2.getGaussianKernel(time_size, s*tau).T[0] + # smoothen the gradient products + Lxy = video_smoothen(Lx * Ly, space_kernel, time_kernel) + Lxt = video_smoothen(Lx * Lt, space_kernel, time_kernel) + Lyt = video_smoothen(Ly * Lt, space_kernel, time_kernel) + Lxx = video_smoothen(Lx * Lx, space_kernel, time_kernel) + Lyy = video_smoothen(Ly * Ly, space_kernel, time_kernel) + Ltt = video_smoothen(Lt * Lt, space_kernel, time_kernel) + # compute Harris response + trace = Lxx + Lyy + Ltt + det = Lxx*(Lyy*Ltt - Lyt*Lyt) - Lxy*(Lxy*Ltt - Lyt*Lxt) + Lxt*(Lxy*Lyt - Lyy*Lxt) + response = (det - kappa * trace * trace * trace) + # find interest points + points = interest_points(response, num=num_points, threshold=threshold, scale=sigma) + return points + +def GaborDetector(v, sigma, tau, threshold, num_points): + """ + Gabor Detector + + Keyword arguments: + video -- input video (y_len, x_len, frames) + sigma -- Gaussian kernel space standard deviation + tau -- Gaussian kernel time standard deviation + kappa -- Gabor response threshold + """ + # setup video + video = v.copy() + video = video.astype(float)/video.max() + video = video_smoothen_space(video, sigma) + # first define a linspace of width -2tau to 2tau + time = np.linspace(-2*tau, 2*tau, int(4*tau+1)) + omega = 4/tau + # define the gabor filters + h_ev = np.exp(-time**2/(2*tau**2)) * np.cos(2*np.pi*omega*time) + h_od = np.exp(-time**2/(2*tau**2)) * np.sin(2*np.pi*omega*time) + # normalize the L1 norm + h_ev /= np.linalg.norm(h_ev, ord=1) + h_od /= np.linalg.norm(h_od, ord=1) + # compute the response + response = (scp.convolve1d(video, h_ev, axis=2) ** 2) + (scp.convolve1d(video, h_od, axis=2) ** 2) + points = interest_points(response, num=num_points, threshold=threshold, scale=sigma) + return points + +def MultiscaleDetector(detector, video, sigmas, tau, num_points): + """ + Multiscale Detector + + Executes a detector at multiple scales. Detector has to be a function that + takes a video as input, along with other parameters, and returns a list of interest points. + + + Keyword arguments: + detector -- function that returns interest points + video -- input video (y_len, x_len, frames) + sigmas -- list of scales + """ + # FIXME: probably needs refactoring. + # the code is clear but super inefficient. + # the gradients are computed a gazillion times. + + # for every scale, compute the Harris response + points = [] + for sigm in sigmas: + found = detector(video, sigm, tau) + points.append(found) + return LogMetricFilter(video, points, tau, num_points) + +def LogMetricFilter(video, points_per_scale, tau, num_points): + """ + Filters interest points according to the log metric + + Keyword arguments: + video -- input video (y_len, x_len, frames) + points_per_scale -- list of interest points + """ + def LogMetric(logs, itemsperscale, N): + # log((x,y), s) = (s^2)|Lxx((x,y),s) + Lyy((x,y),s)| + # returns the coordinates of the points that maximize + # the log metric in a neighborhood of 3 scales + # (prev scale), (curr scale), (next scale) + final = [] + final_logs = [] + for index, items in enumerate(itemsperscale): + logp = logs[max(index-1,0)] + logc = logs[index] + logn = logs[min(index+1,N-1)] + for triplet in items: + y, x, t = int(triplet[0]), int(triplet[1]), int(triplet[2]) + prev = logp[x, y, t] + curr = logc[x, y, t] + next = logn[x, y, t] + if (curr >= prev) and (curr >= next): + final.append(triplet) + final_logs.append(curr) + # get the points with top num_points log metric values + if len(final) > num_points: + indices = np.argsort(final_logs)[::-1] + final_points = [final[i] for i in indices[:num_points]] + return np.array(final_points) + else: + return np.array(final) + v = video.copy() + vnorm = v.astype(float)/video.max() + # compute the laplacian of gaussian (log) metric + logs = [] + time_size = int(2*np.ceil(3*tau)+1) + time_kernel = cv2.getGaussianKernel(time_size, tau).T[0] + # get the sigmas from the points + sigmas = [item[0, 3] for item in points_per_scale] + for sigma in sigmas: + # define Gaussian kernel + space_size = int(2*np.ceil(3*sigma)+1) + space_kernel = cv2.getGaussianKernel(space_size, sigma).T[0] + v = video_smoothen(vnorm, space_kernel, time_kernel) + # compute gradients + Ly, Lx, _ = video_gradients(v) + # compute second order derivatives + Lyy, _, _ = video_gradients(Ly) + _, Lxx, _ = video_gradients(Lx) + # compute the log metric + log = (sigma**2) * np.abs(Lxx + Lyy) + logs.append(log) + # find the points that maximize the log metric + return LogMetric(logs, points_per_scale, len(points_per_scale)) + +def get_hog_descriptors(video, interest_points, nbins): + """ + Compute the HOG descriptors of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) + interest_points -- interest points (y, x, t, s) + sigma -- Gaussian kernel space standard deviation + nbins -- number of bins + """ + # gradients + Ly, Lx, _ = video_gradients(video.astype(float)) + descriptors = [] + for point in interest_points: + side = int(round(4*point[3])) + leftmost = int(max(0, point[0]-side)) + rightmost = int(min(video.shape[1]-1, point[0]+side+1)) + upmost = int(max(0, point[1]-side)) + downmost = int(min(video.shape[0]-1, point[1]+side+1)) + + descriptor = orientation_histogram(Lx[upmost:downmost, leftmost:rightmost, int(point[2])], + Ly[upmost:downmost, leftmost:rightmost, int(point[2])], + nbins, np.array([side, side])) + descriptors.append(descriptor) + return np.array(descriptors, dtype=object) + +def get_hof_descriptors(video, interest_points, nbins): + """ + Compute the HOF descriptors of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) + interest_points -- interest points (y, x, t, s) + sigma -- Gaussian kernel space standard deviation + nbins -- number of bins + """ + oflow = cv2.DualTVL1OpticalFlow_create(nscales=1) + descriptors = [] + for point in interest_points: + side = int(round(4*point[3])) + leftmost = int(max(0, point[0]-side)) + rightmost = int(min(video.shape[1]-1, point[0]+side+1)) + upmost = int(max(0, point[1]-side)) + downmost = int(min(video.shape[0]-1, point[1]+side+1)) + + flow = oflow.calc(video[upmost:downmost, leftmost:rightmost, int(point[2]-1)], + video[upmost:downmost, leftmost:rightmost, int(point[2])], None) + descriptor = orientation_histogram(flow[...,0], flow[...,1], + nbins, np.array([side, side])) + descriptors.append(descriptor) + return np.array(descriptors, dtype=object) + +def get_hog_hof(video, interest_points, nbins): + """ + Compute the HOG and HOF descriptors of a video. + + Keyword arguments: + video -- input video (y_len, x_len, frames) + interest_points -- interest points (y, x, t, s) + sigma -- Gaussian kernel space standard deviation + nbins -- number of bins + """ + hog = get_hog_descriptors(video, interest_points, nbins) + print("HOG: ", hog.shape) + hof = get_hof_descriptors(video, interest_points, nbins) + print("HOF: ", hof.shape) + return np.concatenate((hog, hof)) + + + diff --git a/lab2/part2/gabor.py b/lab2/part2/gabor.py new file mode 100644 index 0000000..9e980a3 --- /dev/null +++ b/lab2/part2/gabor.py @@ -0,0 +1,43 @@ +import os +import sys +import random +from itertools import product +from detector_utils import GaborDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + +RESULTS_FOLDER = "results_trial/gabor_{sigma}_{tau}_{threshold}_{num_points}" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] +PARAMETERS = { + "sigma": [2, 3, 4, 5], + "tau": [1.5, 2, 2.5, 3], + "threshold": [0.1, 0.15, 0.2, 0.25, 0.3], + "num_points": [500] +} + +if __name__ == "__main__": + num_frames = {"walking": 70, "running": 50, "handwaving": 50} + # pick a random video from every category + # find the interest points and save them + combinations = product(*PARAMETERS.values()) + for combination in combinations: + sigma, tau, threshold, num_points = combination + results_folder = RESULTS_FOLDER.format(sigma=sigma, tau=tau, threshold=threshold, num_points=num_points) + for category in CATEGORIES: + frames = num_frames[category] + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, frames, 0) + # get the interest points + gabor_points = GaborDetector(video, sigma, tau, threshold, num_points) + # save the interest points + if not os.path.exists(os.path.join(results_folder, category)): + os.makedirs(os.path.join(results_folder, category)) + show_detection(video, gabor_points, save_path=os.path.join(results_folder, category)) + + diff --git a/lab2/part2/harris.py b/lab2/part2/harris.py new file mode 100644 index 0000000..fb5e406 --- /dev/null +++ b/lab2/part2/harris.py @@ -0,0 +1,41 @@ +import os +import sys +import random +from itertools import product +from detector_utils import HarrisDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + + +RESULTS_FOLDER = "results_trial/harris_{sigma}_{tau}_{threshold}_{num_points}" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] +PARAMETERS = { + "sigma": [2, 3, 4, 5], + "tau": [1.5, 2, 2.5, 3], + "kappa": [0.005], + "threshold": [0.15], + "num_points": [500] +} + +if __name__ == "__main__": + num_frames = 100 + combinations = product(*PARAMETERS.values()) + for combination in combinations: + sigma, tau, kappa, threshold, num_points = combination + results_folder = RESULTS_FOLDER.format(sigma=sigma, tau=tau, threshold=threshold, num_points=num_points) + for category in CATEGORIES: + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, num_frames, 0) + # get the interest points + harris_points = HarrisDetector(video, s=2, sigma=sigma, tau=tau, kappa=0.005, + threshold=threshold, num_points=num_points) + # save the interest points + if not os.path.exists(os.path.join(results_folder, category)): + os.makedirs(os.path.join(results_folder, category)) + show_detection(video, harris_points, save_path=os.path.join(results_folder, category)) \ No newline at end of file diff --git a/lab2/part2/multiscale_gabor.py b/lab2/part2/multiscale_gabor.py new file mode 100644 index 0000000..30d6b34 --- /dev/null +++ b/lab2/part2/multiscale_gabor.py @@ -0,0 +1,33 @@ +import os +import sys +import random +from detector_utils import GaborDetector +from detector_utils import MultiscaleDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + +RESULTS_FOLDER = "results" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] + +if __name__ == "__main__": + num_frames = 100 + # pick a random video from every category + # find the interest points and save them + for category in CATEGORIES: + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, num_frames, 0) + # get the interest points + gabor_points = MultiscaleDetector(lambda video, sigma, tau: + GaborDetector(video, sigma, tau, threshold=0.3, num_points=500), + video, sigmas=[3*(1.1**i) for i in range(6)], tau=1.5, num_points=500) + # save the detection + # check that folder exists + if not os.path.exists(os.path.join(RESULTS_FOLDER, "multiscale_gabor", category)): + os.makedirs(os.path.join(RESULTS_FOLDER, "multiscale_gabor", category)) + show_detection(video, gabor_points, save_path=os.path.join(RESULTS_FOLDER, "multiscale_gabor", category)) diff --git a/lab2/part2/multiscale_harris.py b/lab2/part2/multiscale_harris.py new file mode 100644 index 0000000..b8c7bad --- /dev/null +++ b/lab2/part2/multiscale_harris.py @@ -0,0 +1,35 @@ +import os +import sys +import random +from detector_utils import HarrisDetector +from detector_utils import MultiscaleDetector +from cv23_lab2_2_utils import read_video +from cv23_lab2_2_utils import show_detection + +RESULTS_FOLDER = "results" +DATA_FOLDER = "SpatioTemporal" +CATEGORIES = ["walking", "running", "handwaving"] + +if __name__ == "__main__": + num_frames = 100 + # pick a random video from every category + # find the interest points and save them + for category in CATEGORIES: + # get the video names + video_names = [os.path.join(DATA_FOLDER, category, video_name) + for video_name in os.listdir(os.path.join(DATA_FOLDER, category))] + # pick a random video + video_name = random.choice(video_names) + # read the video + video = read_video(video_name, num_frames, 0) + # get the interest points + + harris_points = MultiscaleDetector(lambda video, sigma, tau: + HarrisDetector(video, 2, sigma, tau, kappa=0.005, threshold=0.05, num_points=500), + video, [3*(1.1**i) for i in range(8)], tau=1.5, num_points=500) + # save the detection + # check that folder exists + if not os.path.exists(os.path.join(RESULTS_FOLDER, "multiscale_harris", category)): + os.makedirs(os.path.join(RESULTS_FOLDER, "multiscale_harris", category)) + show_detection(video, harris_points, + save_path=os.path.join(RESULTS_FOLDER, "multiscale_harris", category)) diff --git a/lab2/part2/test_names.txt b/lab2/part2/test_names.txt new file mode 100644 index 0000000..c4db253 --- /dev/null +++ b/lab2/part2/test_names.txt @@ -0,0 +1,15 @@ +SpatioTemporal/walking/person20_walking_d3_uncomp.avi +SpatioTemporal/running/person25_running_d4_uncomp.avi +SpatioTemporal/handwaving/person25_handwaving_d1_uncomp.avi +SpatioTemporal/walking/person13_walking_d3_uncomp.avi +SpatioTemporal/handwaving/person23_handwaving_d3_uncomp.avi +SpatioTemporal/handwaving/person04_handwaving_d1_uncomp.avi +SpatioTemporal/running/person05_running_d1_uncomp.avi +SpatioTemporal/handwaving/person06_handwaving_d1_uncomp.avi +SpatioTemporal/handwaving/person03_handwaving_d4_uncomp.avi +SpatioTemporal/running/person10_running_d2_uncomp.avi +SpatioTemporal/walking/person05_walking_d2_uncomp.avi +SpatioTemporal/handwaving/person21_handwaving_d1_uncomp.avi +SpatioTemporal/walking/person11_walking_d1_uncomp.avi +SpatioTemporal/handwaving/person09_handwaving_d4_uncomp.avi +SpatioTemporal/running/person03_running_d3_uncomp.avi \ No newline at end of file diff --git a/lab2/part2/train_names.txt b/lab2/part2/train_names.txt new file mode 100644 index 0000000..0231863 --- /dev/null +++ b/lab2/part2/train_names.txt @@ -0,0 +1,33 @@ +SpatioTemporal/handwaving/person05_handwaving_d2_uncomp.avi +SpatioTemporal/running/person20_running_d1_uncomp.avi +SpatioTemporal/handwaving/person22_handwaving_d2_uncomp.avi +SpatioTemporal/walking/person16_walking_d2_uncomp.avi +SpatioTemporal/running/person06_running_d3_uncomp.avi +SpatioTemporal/running/person01_running_d1_uncomp.avi +SpatioTemporal/running/person02_running_d2_uncomp.avi +SpatioTemporal/handwaving/person11_handwaving_d2_uncomp.avi +SpatioTemporal/handwaving/person15_handwaving_d4_uncomp.avi +SpatioTemporal/walking/person06_walking_d3_uncomp.avi +SpatioTemporal/running/person08_running_d4_uncomp.avi +SpatioTemporal/walking/person08_walking_d2_uncomp.avi +SpatioTemporal/handwaving/person24_handwaving_d4_uncomp.avi +SpatioTemporal/handwaving/person12_handwaving_d3_uncomp.avi +SpatioTemporal/running/person09_running_d1_uncomp.avi +SpatioTemporal/walking/person04_walking_d1_uncomp.avi +SpatioTemporal/walking/person14_walking_d4_uncomp.avi +SpatioTemporal/walking/person07_walking_d4_uncomp.avi +SpatioTemporal/running/person23_running_d2_uncomp.avi +SpatioTemporal/running/person24_running_d3_uncomp.avi +SpatioTemporal/walking/person18_walking_d4_uncomp.avi +SpatioTemporal/walking/person25_walking_d4_uncomp.avi +SpatioTemporal/walking/person19_walking_d1_uncomp.avi +SpatioTemporal/walking/person17_walking_d3_uncomp.avi +SpatioTemporal/handwaving/person01_handwaving_d2_uncomp.avi +SpatioTemporal/walking/person15_walking_d1_uncomp.avi +SpatioTemporal/running/person06_running_d2_uncomp.avi +SpatioTemporal/running/person21_running_d4_uncomp.avi +SpatioTemporal/handwaving/person02_handwaving_d3_uncomp.avi +SpatioTemporal/walking/person12_walking_d2_uncomp.avi +SpatioTemporal/running/person04_running_d4_uncomp.avi +SpatioTemporal/handwaving/person07_handwaving_d3_uncomp.avi +SpatioTemporal/running/person07_running_d3_uncomp.avi \ No newline at end of file diff --git a/lab2/part3/ImageStitching/img1_ratio01.jpg b/lab2/part3/ImageStitching/img1_ratio01.jpg new file mode 100644 index 0000000..9884f75 Binary files /dev/null and b/lab2/part3/ImageStitching/img1_ratio01.jpg differ diff --git a/lab2/part3/ImageStitching/img2_ratio01.jpg b/lab2/part3/ImageStitching/img2_ratio01.jpg new file mode 100644 index 0000000..371b267 Binary files /dev/null and b/lab2/part3/ImageStitching/img2_ratio01.jpg differ diff --git a/lab2/part3/ImageStitching/img3_ratio01.jpg b/lab2/part3/ImageStitching/img3_ratio01.jpg new file mode 100644 index 0000000..c98b87c Binary files /dev/null and b/lab2/part3/ImageStitching/img3_ratio01.jpg differ diff --git a/lab2/part3/ImageStitching/img4_ratio01.jpg b/lab2/part3/ImageStitching/img4_ratio01.jpg new file mode 100644 index 0000000..16ee27c Binary files /dev/null and b/lab2/part3/ImageStitching/img4_ratio01.jpg differ diff --git a/lab2/part3/ImageStitching/img5_ratio01.jpg b/lab2/part3/ImageStitching/img5_ratio01.jpg new file mode 100644 index 0000000..4dac059 Binary files /dev/null and b/lab2/part3/ImageStitching/img5_ratio01.jpg differ diff --git a/lab2/part3/ImageStitching/img6_ratio01.jpg b/lab2/part3/ImageStitching/img6_ratio01.jpg new file mode 100644 index 0000000..0fcc146 Binary files /dev/null and b/lab2/part3/ImageStitching/img6_ratio01.jpg differ diff --git a/lab2/part3/StichingResults/final_stitched.jpg b/lab2/part3/StichingResults/final_stitched.jpg new file mode 100644 index 0000000..0d70199 Binary files /dev/null and b/lab2/part3/StichingResults/final_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img1_2_stitched.jpg b/lab2/part3/StichingResults/img1_2_stitched.jpg new file mode 100644 index 0000000..58eafe3 Binary files /dev/null and b/lab2/part3/StichingResults/img1_2_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img1_3_stitched.jpg b/lab2/part3/StichingResults/img1_3_stitched.jpg new file mode 100644 index 0000000..227ec22 Binary files /dev/null and b/lab2/part3/StichingResults/img1_3_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img1_3_stitched_all.jpg b/lab2/part3/StichingResults/img1_3_stitched_all.jpg new file mode 100644 index 0000000..c5009f0 Binary files /dev/null and b/lab2/part3/StichingResults/img1_3_stitched_all.jpg differ diff --git a/lab2/part3/StichingResults/img1_4_stitched_all.jpg b/lab2/part3/StichingResults/img1_4_stitched_all.jpg new file mode 100644 index 0000000..45401eb Binary files /dev/null and b/lab2/part3/StichingResults/img1_4_stitched_all.jpg differ diff --git a/lab2/part3/StichingResults/img2_3_stitched.jpg b/lab2/part3/StichingResults/img2_3_stitched.jpg new file mode 100644 index 0000000..92d7f23 Binary files /dev/null and b/lab2/part3/StichingResults/img2_3_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img3_4_stitched.jpg b/lab2/part3/StichingResults/img3_4_stitched.jpg new file mode 100644 index 0000000..d0ce523 Binary files /dev/null and b/lab2/part3/StichingResults/img3_4_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img3_5_stitched.jpg b/lab2/part3/StichingResults/img3_5_stitched.jpg new file mode 100644 index 0000000..6105a0c Binary files /dev/null and b/lab2/part3/StichingResults/img3_5_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img3_6_stitched_all.jpg b/lab2/part3/StichingResults/img3_6_stitched_all.jpg new file mode 100644 index 0000000..436414b Binary files /dev/null and b/lab2/part3/StichingResults/img3_6_stitched_all.jpg differ diff --git a/lab2/part3/StichingResults/img4_5_stitched.jpg b/lab2/part3/StichingResults/img4_5_stitched.jpg new file mode 100644 index 0000000..9632257 Binary files /dev/null and b/lab2/part3/StichingResults/img4_5_stitched.jpg differ diff --git a/lab2/part3/StichingResults/img4_6_stitched_all.jpg b/lab2/part3/StichingResults/img4_6_stitched_all.jpg new file mode 100644 index 0000000..e4a3007 Binary files /dev/null and b/lab2/part3/StichingResults/img4_6_stitched_all.jpg differ diff --git a/lab2/part3/StichingResults/img5_6_stitched.jpg b/lab2/part3/StichingResults/img5_6_stitched.jpg new file mode 100644 index 0000000..87b2d52 Binary files /dev/null and b/lab2/part3/StichingResults/img5_6_stitched.jpg differ diff --git a/lab2/part3/StichingResults/matching.jpg b/lab2/part3/StichingResults/matching.jpg new file mode 100644 index 0000000..9de7d25 Binary files /dev/null and b/lab2/part3/StichingResults/matching.jpg differ diff --git a/lab2/part3/StichingResults/warped.jpg b/lab2/part3/StichingResults/warped.jpg new file mode 100644 index 0000000..ebe4d7f Binary files /dev/null and b/lab2/part3/StichingResults/warped.jpg differ diff --git a/lab2/part3/StichingResultsTrial/img1_2_stitched.jpg b/lab2/part3/StichingResultsTrial/img1_2_stitched.jpg new file mode 100644 index 0000000..4086c20 Binary files /dev/null and b/lab2/part3/StichingResultsTrial/img1_2_stitched.jpg differ diff --git a/lab2/part3/StichingResultsTrial/img2_3_stitched.jpg b/lab2/part3/StichingResultsTrial/img2_3_stitched.jpg new file mode 100644 index 0000000..6105a0c Binary files /dev/null and b/lab2/part3/StichingResultsTrial/img2_3_stitched.jpg differ diff --git a/lab2/part3/StichingResultsTrial/img3_4_stitched.jpg b/lab2/part3/StichingResultsTrial/img3_4_stitched.jpg new file mode 100644 index 0000000..3b939c9 Binary files /dev/null and b/lab2/part3/StichingResultsTrial/img3_4_stitched.jpg differ diff --git a/lab2/part3/StichingResultsTrial/img4_5_stitched.jpg b/lab2/part3/StichingResultsTrial/img4_5_stitched.jpg new file mode 100644 index 0000000..d552211 Binary files /dev/null and b/lab2/part3/StichingResultsTrial/img4_5_stitched.jpg differ diff --git a/lab2/part3/StichingResultsTrial/img5_6_stitched.jpg b/lab2/part3/StichingResultsTrial/img5_6_stitched.jpg new file mode 100644 index 0000000..bbf9aba Binary files /dev/null and b/lab2/part3/StichingResultsTrial/img5_6_stitched.jpg differ diff --git a/lab2/part3/stitching.py b/lab2/part3/stitching.py new file mode 100644 index 0000000..f9087e7 --- /dev/null +++ b/lab2/part3/stitching.py @@ -0,0 +1,36 @@ +import os +import cv2 +import matplotlib.pyplot as plt +from stitching_utils import stitchImages + + +IMAGE_PATH = 'ImageStitching' +IMAGE_NAME = 'img{num}_ratio01.jpg' +RESULT_PATH = 'StichingResults' +RESULT_NAME = 'img{num1}_{num2}_stitched.jpg' +RESULT_NAME_ALL = 'img{num1}_{num2}_stitched_all.jpg' +NUM_IMAGES = 6 + +START = False + +def main(): + # check if result path exists + if not os.path.exists(RESULT_PATH): + os.makedirs(RESULT_PATH) + # stitch images + # check if stitched images exist + if START: + for i in range(1, NUM_IMAGES): + img1 = cv2.imread(IMAGE_PATH + '/' + IMAGE_NAME.format(num=i)) + img2 = cv2.imread(IMAGE_PATH + '/' + IMAGE_NAME.format(num=i+1)) + stitched_img = stitchImages(img1, img2, match='bf') + cv2.imwrite(RESULT_PATH + '/' + RESULT_NAME.format(num1=i, num2=i+1), stitched_img) + else: + img1 = cv2.imread(IMAGE_PATH + '/' + IMAGE_NAME.format(num=2)) + img2 = cv2.imread(IMAGE_PATH + '/' + IMAGE_NAME.format(num=3)) + stitched_img = stitchImages(img1, img2, match='bf') + + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/lab2/part3/stitching_utils.py b/lab2/part3/stitching_utils.py new file mode 100644 index 0000000..13f038b --- /dev/null +++ b/lab2/part3/stitching_utils.py @@ -0,0 +1,163 @@ +import cv2 +import numpy as np +from matplotlib import pyplot as plt + + + +def combine_images(img1, img2, H): + """ + Combine two images together. + + Keyword arguments: + img1 -- first image + img2 -- second image + H -- homography matrix + """ + points1 = np.array([[0, 0], [0, img1.shape[0]], [img1.shape[1], img1.shape[0]], [img1.shape[1], 0]], dtype=np.float32) + points1 = points1.reshape((-1, 1, 2)) + + points2 = np.array([[0, 0], [0, img2.shape[0]], [img2.shape[1], img2.shape[0]], [img2.shape[1], 0]], dtype=np.float32) + points2 = points2.reshape((-1, 1, 2)) + + warped_points1 = cv2.perspectiveTransform(points1, H)[0] + warped_points1 = warped_points1.astype(np.int32) + warped_points1 = warped_points1.reshape((-1, 1, 2)) + + points = np.concatenate((points2, warped_points1), axis=0) + + [x_min, y_min] = np.min(points, axis=0).ravel().astype(np.int32) + [x_max, y_max] = np.max(points, axis=0).ravel().astype(np.int32) + + T = np.array([[1, 0, -x_min], [0, 1, -y_min], [0, 0, 1]], dtype=np.float32) + + output = cv2.warpPerspective(img1, T.dot(H), (x_max-x_min, y_max-y_min)) + # show warped image + plt.imshow(output) + plt.show() + cv2.imwrite('StichingResults/warped.jpg', output) + exit() + output[-y_min:img2.shape[0]-y_min, -x_min:img2.shape[1]-x_min] = img2 + + return output + +def projectionImage(H, img): + """ + Apply inverse warping to img. + + Keyword arguments: + H -- homography matrix + img -- image to be warped + """ + + # Step1: Compute the warped coordinates of the four corners of the image + # to obtain the coordinate of the top-left corner and bottom-right corner + # of the warped image + h, w = img.shape[:2] + corners = np.array([[0, 0], [0, h], [w, h], [w, 0]], dtype=np.float32) + corners = np.array([corners]) + + warped_corners = cv2.perspectiveTransform(corners, H)[0] + warped_corners = warped_corners.astype(np.int32) + + warped_topleft_coords = warped_corners.min(axis=0) + warped_bottomright_coords = warped_corners.max(axis=0) + + # Step2: Compute the translation matrix that will shift the image + # such that the top-left corner of the image will move to the origin + # (0, 0) of the coordinate system + [x_min, y_min] = warped_topleft_coords + [x_max, y_max] = warped_bottomright_coords + tx = -warped_topleft_coords[0] + ty = -warped_topleft_coords[1] + T = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]], dtype=np.float32) + + # Step3: Compute the warped image by applying the inverse warping matrix + # to the image + warped_img = cv2.warpPerspective(img, T.dot(H), + (x_max-x_min, y_max-y_min)) + warped_img[-y_min:h-y_min, -x_min:w-x_min] = img + return warped_img, warped_topleft_coords + +def mergeWarpedImages(img1_warped, img2, img1_topleft_coords): + """ + Merge the warped version of img1 with img2 under the same coordinate system of img2. + + Keyword arguments: + img1_warped -- warped version of img1 + img2 -- second image + img1_topleft_coords -- top-left corner coordinates of img1 + """ + + # Step1: Compute the translation matrix that will shift the image + # such that the top-left corner of the image will move to the origin + # (0, 0) of the coordinate system + tx = -img1_topleft_coords[0] + ty = -img1_topleft_coords[1] + T = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]], dtype=np.float32) + + # Step2: Compute the merged image by applying the translation matrix + # to the warped image and then merging it with the second image + merged_img = cv2.warpPerspective(img1_warped, T, (img2.shape[1], img2.shape[0])) + + merged_img[0:img2.shape[0], 0:img2.shape[1]] = img2 + + return merged_img + + +def stitchImages(img1, img2, match = 'bf'): + """ + Stitch two images together. + + Keyword arguments: + img1 -- first image + img2 -- second image + """ + + # Step1: Extract SIFT features and descriptors from both images + sift1 = cv2.xfeatures2d.SIFT_create() + sift2 = cv2.xfeatures2d.SIFT_create() + keypoints1, descriptors1 = sift1.detectAndCompute(img1, None) + keypoints2, descriptors2 = sift2.detectAndCompute(img2, None) + # Convert keypoints to numpy arrays + points1 = np.float32([kp.pt for kp in keypoints1]).reshape(-1, 1, 2) + points2 = np.float32([kp.pt for kp in keypoints2]).reshape(-1, 1, 2) + + # Step2: Match features by applying Brute-Force-based or FLANN-based matching + k = 2 + if match == 'bf': + bf = cv2.BFMatcher() + matches = bf.knnMatch(descriptors1, descriptors2, k) + elif match == 'flann': + index_params = dict(algorithm=0, trees=5) + search_params = dict(checks=50) + flann = cv2.FlannBasedMatcher(index_params, search_params) + matches = flann.knnMatch(descriptors1, descriptors2, k) + + # Step3: Apply Lowe's criterion to speedily reject most outliers + good = [] + for m, n in matches: + if m.distance < 0.7 * n.distance: + good.append(m) + matches = good + + points1 = np.float32([points1[m.queryIdx] for m in matches]).reshape(-1, 1, 2) + points2 = np.float32([points2[m.trainIdx] for m in matches]).reshape(-1, 1, 2) + + # Step4: Compute RANSAC-based Homography H + # given the matches between image 1 and image 2 + # we compute the homography H21 that maps + # points from image 1 to image 2 + # x2 = H21 * x1 + H = cv2.findHomography(points1, points2, cv2.RANSAC, 5.0)[0] + + # Step5: Apply inverse warping to img1 + # img1_warped, img1_topleft_coords = projectionImage(H, img1) + + # Step6: Merge the warped version of img1 with img2 under the same coordinate system of img2 + + # stiched_img = mergeWarpedImages(img1_warped, img2, img1_topleft_coords) + + # the combination of the above do not work + # this works + stiched_img = combine_images(img1, img2, H) + return stiched_img \ No newline at end of file diff --git a/lab2/report/lab2_report.aux b/lab2/report/lab2_report.aux new file mode 100644 index 0000000..29c1f3c --- /dev/null +++ b/lab2/report/lab2_report.aux @@ -0,0 +1,77 @@ +\relax +\providecommand\babel@aux[2]{} +\@nameuse{bbl@beforestart} +\catcode `;\active +\babel@aux{greek}{} +\@writefile{toc}{\contentsline {section}{\numberline {1}Μέρος 1}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Ανίχνευση Δέρματος Προσώπου και Χεριών}{3}{}\protected@file@percent } +\providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}} +\newlabel{fig:binary-skin-bad}{{1{\greekscript \textalpha \textnumeralsigngreek }}{3}} +\newlabel{sub@fig:binary-skin-bad}{{{\greekscript \textalpha \textnumeralsigngreek }}{3}} +\newlabel{fig:binary-skin-good}{{1{\greekscript \textbeta \textnumeralsigngreek }}{3}} +\newlabel{sub@fig:binary-skin-good}{{{\greekscript \textbeta \textnumeralsigngreek }}{3}} +\newlabel{fig:}{{2{\greekscript \textalpha \textnumeralsigngreek }}{4}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{4}} +\newlabel{fig:}{{2{\greekscript \textbeta \textnumeralsigngreek }}{4}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{4}} +\newlabel{fig:}{{2{\greekscript \textgamma \textnumeralsigngreek }}{4}} +\newlabel{sub@fig:}{{{\greekscript \textgamma \textnumeralsigngreek }}{4}} +\newlabel{fig:}{{2{\greekscript \textdelta \textnumeralsigngreek }}{4}} +\newlabel{sub@fig:}{{{\greekscript \textdelta \textnumeralsigngreek }}{4}} +\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Ενδεικτικός εντοπισμός δέρματος σε μερικά πλαίσια\relax }}{4}{}\protected@file@percent } +\newlabel{fig:skin-detection}{{2}{4}} +\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Παρακολούθηδη Προσώπου και Χεριών}{5}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.1}Υλοποίηση Αλγορίθμου \foreignlanguage {english}{Lucas-Kanade}}{5}{}\protected@file@percent } +\newlabel{fig:}{{3{\greekscript \textalpha \textnumeralsigngreek }}{5}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{5}} +\newlabel{fig:}{{3{\greekscript \textbeta \textnumeralsigngreek }}{5}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{5}} +\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Ενδεικτικός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής\relax }}{5}{}\protected@file@percent } +\newlabel{fig:tracking1}{{3}{5}} +\newlabel{fig:}{{4{\greekscript \textalpha \textnumeralsigngreek }}{6}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{6}} +\newlabel{fig:}{{4{\greekscript \textbeta \textnumeralsigngreek }}{6}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{6}} +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Ενδεικτικός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής\relax }}{6}{}\protected@file@percent } +\newlabel{fig:tracking2}{{4}{6}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.2}Υπολογισμός Μετατόπισης Παραθύρων και Οπτικής Ροής}{7}{}\protected@file@percent } +\newlabel{fig:}{{5{\greekscript \textalpha \textnumeralsigngreek }}{7}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{7}} +\newlabel{fig:}{{5{\greekscript \textbeta \textnumeralsigngreek }}{7}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{7}} +\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια\relax }}{7}{}\protected@file@percent } +\newlabel{fig:flows1}{{5}{7}} +\newlabel{fig:}{{6{\greekscript \textalpha \textnumeralsigngreek }}{7}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{7}} +\newlabel{fig:}{{6{\greekscript \textbeta \textnumeralsigngreek }}{7}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{7}} +\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια\relax }}{7}{}\protected@file@percent } +\newlabel{fig:flows2}{{6}{7}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.2.3}Πολυ-κλιμακωτός Υπολογισμός Οπτικής Ροής}{8}{}\protected@file@percent } +\newlabel{fig:}{{7{\greekscript \textalpha \textnumeralsigngreek }}{8}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{8}} +\newlabel{fig:}{{7{\greekscript \textbeta \textnumeralsigngreek }}{8}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{8}} +\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Ενδεικτικός πολυκλιμακωτός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής\relax }}{8}{}\protected@file@percent } +\newlabel{fig:tracking_multiscale1}{{7}{8}} +\newlabel{fig:}{{8{\greekscript \textalpha \textnumeralsigngreek }}{8}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{8}} +\newlabel{fig:}{{8{\greekscript \textbeta \textnumeralsigngreek }}{8}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{8}} +\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Ενδεικτικός πολυκλιμακωτός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής\relax }}{8}{}\protected@file@percent } +\newlabel{fig:tracking_multiscale2}{{8}{8}} +\newlabel{fig:}{{9{\greekscript \textalpha \textnumeralsigngreek }}{9}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{9}} +\newlabel{fig:}{{9{\greekscript \textbeta \textnumeralsigngreek }}{9}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{9}} +\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Πολυκλιμακωτός εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια\relax }}{9}{}\protected@file@percent } +\newlabel{fig:flow_multiscales1}{{9}{9}} +\newlabel{fig:}{{10{\greekscript \textalpha \textnumeralsigngreek }}{9}} +\newlabel{sub@fig:}{{{\greekscript \textalpha \textnumeralsigngreek }}{9}} +\newlabel{fig:}{{10{\greekscript \textbeta \textnumeralsigngreek }}{9}} +\newlabel{sub@fig:}{{{\greekscript \textbeta \textnumeralsigngreek }}{9}} +\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Πολυκλιμακωτός εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια\relax }}{9}{}\protected@file@percent } +\newlabel{fig:flow_multiscales2}{{10}{9}} +\@writefile{toc}{\contentsline {section}{\numberline {2}Μέρος 2}{10}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {3}Μέρος 3}{11}{}\protected@file@percent } +\gdef \@abspage@last{11} diff --git a/lab2/report/lab2_report.log b/lab2/report/lab2_report.log new file mode 100644 index 0000000..59fabc6 --- /dev/null +++ b/lab2/report/lab2_report.log @@ -0,0 +1,952 @@ +This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=pdflatex 2023.6.1) 14 JUN 2023 01:05 +entering extended mode + restricted \write18 enabled. + %&-line parsing enabled. +**lab2_report.tex +(./lab2_report.tex +LaTeX2e <2021-11-15> patch level 1 +L3 programming layer <2022-01-21> +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2021/10/04 v1.4n Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo +File: size10.clo 2021/10/04 v1.4n Standard LaTeX file (size option) +) +\c@part=\count185 +\c@section=\count186 +\c@subsection=\count187 +\c@subsubsection=\count188 +\c@paragraph=\count189 +\c@subparagraph=\count190 +\c@figure=\count191 +\c@table=\count192 +\abovecaptionskip=\skip47 +\belowcaptionskip=\skip48 +\bibindent=\dimen138 +) +(/usr/share/texlive/texmf-dist/tex/latex/preprint/fullpage.sty +Package: fullpage 1999/02/23 1.1 (PWD) +\FP@margin=\skip49 +) +(/usr/share/texlive/texmf-dist/tex/generic/babel/babel.sty +Package: babel 2022/01/26 3.70 The Babel package +\babel@savecnt=\count193 +\U@D=\dimen139 +\l@unhyphenated=\language7 + +(/usr/share/texlive/texmf-dist/tex/generic/babel/txtbabel.def) +\bbl@readstream=\read2 +\bbl@dirlevel=\count194 + +(/usr/share/texlive/texmf-dist/tex/generic/babel-english/english.ldf +Language: english 2017/06/06 v3.3r English support from the babel system +Package babel Info: Hyphen rules for 'british' set to \l@english +(babel) (\language0). Reported on input line 82. +Package babel Info: Hyphen rules for 'UKenglish' set to \l@english +(babel) (\language0). Reported on input line 83. +Package babel Info: Hyphen rules for 'canadian' set to \l@english +(babel) (\language0). Reported on input line 102. +Package babel Info: Hyphen rules for 'australian' set to \l@english +(babel) (\language0). Reported on input line 105. +Package babel Info: Hyphen rules for 'newzealand' set to \l@english +(babel) (\language0). Reported on input line 108. +) +(/usr/share/texlive/texmf-dist/tex/generic/babel-greek/greek.ldf +Language: greek 2020/11/10 v1.10 Greek support for the babel system +\bbl@monogreek=\count195 +\bbl@polygreek=\count196 +\bbl@ancientgreek=\count197 + +(/usr/share/texlive/texmf-dist/tex/latex/greek-fontenc/lgrenc.def +File: lgrenc.def 2020/10/13 2.0 LGR Greek font encoding definitions +Now handling font encoding LGR ... +... processing UTF-8 mapping file for font encoding LGR + +(/usr/share/texlive/texmf-dist/tex/latex/greek-inputenc/lgrenc.dfu +File: lgrenc.dfu 2019/07/11 1.7 UTF-8 support for Greek + defining Unicode char U+00A8 (decimal 168) + defining Unicode char U+00AB (decimal 171) + defining Unicode char U+00AF (decimal 175) + defining Unicode char U+00B4 (decimal 180) + defining Unicode char U+00B7 (decimal 183) + defining Unicode char U+00BB (decimal 187) + defining Unicode char U+0259 (decimal 601) + defining Unicode char U+02D8 (decimal 728) + defining Unicode char U+0374 (decimal 884) + defining Unicode char U+0375 (decimal 885) + defining Unicode char U+037A (decimal 890) + defining Unicode char U+037E (decimal 894) + defining Unicode char U+0384 (decimal 900) + defining Unicode char U+0385 (decimal 901) + defining Unicode char U+0386 (decimal 902) + defining Unicode char U+0387 (decimal 903) + defining Unicode char U+0388 (decimal 904) + defining Unicode char U+0389 (decimal 905) + defining Unicode char U+038A (decimal 906) + defining Unicode char U+038C (decimal 908) + defining Unicode char U+038E (decimal 910) + defining Unicode char U+038F (decimal 911) + defining Unicode char U+0390 (decimal 912) + defining Unicode char U+0391 (decimal 913) + defining Unicode char U+0392 (decimal 914) + defining Unicode char U+0393 (decimal 915) + defining Unicode char U+0394 (decimal 916) + defining Unicode char U+0395 (decimal 917) + defining Unicode char U+0396 (decimal 918) + defining Unicode char U+0397 (decimal 919) + defining Unicode char U+0398 (decimal 920) + defining Unicode char U+0399 (decimal 921) + defining Unicode char U+039A (decimal 922) + defining Unicode char U+039B (decimal 923) + defining Unicode char U+039C (decimal 924) + defining Unicode char U+039D (decimal 925) + defining Unicode char U+039E (decimal 926) + defining Unicode char U+039F (decimal 927) + defining Unicode char U+03A0 (decimal 928) + defining Unicode char U+03A1 (decimal 929) + defining Unicode char U+03A3 (decimal 931) + defining Unicode char U+03A4 (decimal 932) + defining Unicode char U+03A5 (decimal 933) + defining Unicode char U+03A6 (decimal 934) + defining Unicode char U+03A7 (decimal 935) + defining Unicode char U+03A8 (decimal 936) + defining Unicode char U+03A9 (decimal 937) + defining Unicode char U+03AA (decimal 938) + defining Unicode char U+03AB (decimal 939) + defining Unicode char U+03AC (decimal 940) + defining Unicode char U+03AD (decimal 941) + defining Unicode char U+03AE (decimal 942) + defining Unicode char U+03AF (decimal 943) + defining Unicode char U+03B0 (decimal 944) + defining Unicode char U+03B1 (decimal 945) + defining Unicode char U+03B2 (decimal 946) + defining Unicode char U+03B3 (decimal 947) + defining Unicode char U+03B4 (decimal 948) + defining Unicode char U+03B5 (decimal 949) + defining Unicode char U+03B6 (decimal 950) + defining Unicode char U+03B7 (decimal 951) + defining Unicode char U+03B8 (decimal 952) + defining Unicode char U+03B9 (decimal 953) + defining Unicode char U+03BA (decimal 954) + defining Unicode char U+03BB (decimal 955) + defining Unicode char U+03BC (decimal 956) + defining Unicode char U+03BD (decimal 957) + defining Unicode char U+03BE (decimal 958) + defining Unicode char U+03BF (decimal 959) + defining Unicode char U+03C0 (decimal 960) + defining Unicode char U+03C1 (decimal 961) + defining Unicode char U+03C2 (decimal 962) + defining Unicode char U+03C3 (decimal 963) + defining Unicode char U+03C4 (decimal 964) + defining Unicode char U+03C5 (decimal 965) + defining Unicode char U+03C6 (decimal 966) + defining Unicode char U+03C7 (decimal 967) + defining Unicode char U+03C8 (decimal 968) + defining Unicode char U+03C9 (decimal 969) + defining Unicode char U+03CA (decimal 970) + defining Unicode char U+03CB (decimal 971) + defining Unicode char U+03CC (decimal 972) + defining Unicode char U+03CD (decimal 973) + defining Unicode char U+03CE (decimal 974) + defining Unicode char U+03D0 (decimal 976) + defining Unicode char U+03D1 (decimal 977) + defining Unicode char U+03D5 (decimal 981) + defining Unicode char U+03D6 (decimal 982) + defining Unicode char U+03D8 (decimal 984) + defining Unicode char U+03D9 (decimal 985) + defining Unicode char U+03DA (decimal 986) + defining Unicode char U+03DB (decimal 987) + defining Unicode char U+03DC (decimal 988) + defining Unicode char U+03DD (decimal 989) + defining Unicode char U+03DF (decimal 991) + defining Unicode char U+03E0 (decimal 992) + defining Unicode char U+03E1 (decimal 993) + defining Unicode char U+03F0 (decimal 1008) + defining Unicode char U+03F1 (decimal 1009) + defining Unicode char U+03F4 (decimal 1012) + defining Unicode char U+03F5 (decimal 1013) + defining Unicode char U+1F00 (decimal 7936) + defining Unicode char U+1F01 (decimal 7937) + defining Unicode char U+1F02 (decimal 7938) + defining Unicode char U+1F03 (decimal 7939) + defining Unicode char U+1F04 (decimal 7940) + defining Unicode char U+1F05 (decimal 7941) + defining Unicode char U+1F06 (decimal 7942) + defining Unicode char U+1F07 (decimal 7943) + defining Unicode char U+1F08 (decimal 7944) + defining Unicode char U+1F09 (decimal 7945) + defining Unicode char U+1F0A (decimal 7946) + defining Unicode char U+1F0B (decimal 7947) + defining Unicode char U+1F0C (decimal 7948) + defining Unicode char U+1F0D (decimal 7949) + defining Unicode char U+1F0E (decimal 7950) + defining Unicode char U+1F0F (decimal 7951) + defining Unicode char U+1F10 (decimal 7952) + defining Unicode char U+1F11 (decimal 7953) + defining Unicode char U+1F12 (decimal 7954) + defining Unicode char U+1F13 (decimal 7955) + defining Unicode char U+1F14 (decimal 7956) + defining Unicode char U+1F15 (decimal 7957) + defining Unicode char U+1F18 (decimal 7960) + defining Unicode char U+1F19 (decimal 7961) + defining Unicode char U+1F1A (decimal 7962) + defining Unicode char U+1F1B (decimal 7963) + defining Unicode char U+1F1C (decimal 7964) + defining Unicode char U+1F1D (decimal 7965) + defining Unicode char U+1F20 (decimal 7968) + defining Unicode char U+1F21 (decimal 7969) + defining Unicode char U+1F22 (decimal 7970) + defining Unicode char U+1F23 (decimal 7971) + defining Unicode char U+1F24 (decimal 7972) + defining Unicode char U+1F25 (decimal 7973) + defining Unicode char U+1F26 (decimal 7974) + defining Unicode char U+1F27 (decimal 7975) + defining Unicode char U+1F28 (decimal 7976) + defining Unicode char U+1F29 (decimal 7977) + defining Unicode char U+1F2A (decimal 7978) + defining Unicode char U+1F2B (decimal 7979) + defining Unicode char U+1F2C (decimal 7980) + defining Unicode char U+1F2D (decimal 7981) + defining Unicode char U+1F2E (decimal 7982) + defining Unicode char U+1F2F (decimal 7983) + defining Unicode char U+1F30 (decimal 7984) + defining Unicode char U+1F31 (decimal 7985) + defining Unicode char U+1F32 (decimal 7986) + defining Unicode char U+1F33 (decimal 7987) + defining Unicode char U+1F34 (decimal 7988) + defining Unicode char U+1F35 (decimal 7989) + defining Unicode char U+1F36 (decimal 7990) + defining Unicode char U+1F37 (decimal 7991) + defining Unicode char U+1F38 (decimal 7992) + defining Unicode char U+1F39 (decimal 7993) + defining Unicode char U+1F3A (decimal 7994) + defining Unicode char U+1F3B (decimal 7995) + defining Unicode char U+1F3C (decimal 7996) + defining Unicode char U+1F3D (decimal 7997) + defining Unicode char U+1F3E (decimal 7998) + defining Unicode char U+1F3F (decimal 7999) + defining Unicode char U+1F40 (decimal 8000) + defining Unicode char U+1F41 (decimal 8001) + defining Unicode char U+1F42 (decimal 8002) + defining Unicode char U+1F43 (decimal 8003) + defining Unicode char U+1F44 (decimal 8004) + defining Unicode char U+1F45 (decimal 8005) + defining Unicode char U+1F48 (decimal 8008) + defining Unicode char U+1F49 (decimal 8009) + defining Unicode char U+1F4A (decimal 8010) + defining Unicode char U+1F4B (decimal 8011) + defining Unicode char U+1F4C (decimal 8012) + defining Unicode char U+1F4D (decimal 8013) + defining Unicode char U+1F50 (decimal 8016) + defining Unicode char U+1F51 (decimal 8017) + defining Unicode char U+1F52 (decimal 8018) + defining Unicode char U+1F53 (decimal 8019) + defining Unicode char U+1F54 (decimal 8020) + defining Unicode char U+1F55 (decimal 8021) + defining Unicode char U+1F56 (decimal 8022) + defining Unicode char U+1F57 (decimal 8023) + defining Unicode char U+1F59 (decimal 8025) + defining Unicode char U+1F5B (decimal 8027) + defining Unicode char U+1F5D (decimal 8029) + defining Unicode char U+1F5F (decimal 8031) + defining Unicode char U+1F60 (decimal 8032) + defining Unicode char U+1F61 (decimal 8033) + defining Unicode char U+1F62 (decimal 8034) + defining Unicode char U+1F63 (decimal 8035) + defining Unicode char U+1F64 (decimal 8036) + defining Unicode char U+1F65 (decimal 8037) + defining Unicode char U+1F66 (decimal 8038) + defining Unicode char U+1F67 (decimal 8039) + defining Unicode char U+1F68 (decimal 8040) + defining Unicode char U+1F69 (decimal 8041) + defining Unicode char U+1F6A (decimal 8042) + defining Unicode char U+1F6B (decimal 8043) + defining Unicode char U+1F6C (decimal 8044) + defining Unicode char U+1F6D (decimal 8045) + defining Unicode char U+1F6E (decimal 8046) + defining Unicode char U+1F6F (decimal 8047) + defining Unicode char U+1F70 (decimal 8048) + defining Unicode char U+1F71 (decimal 8049) + defining Unicode char U+1F72 (decimal 8050) + defining Unicode char U+1F73 (decimal 8051) + defining Unicode char U+1F74 (decimal 8052) + defining Unicode char U+1F75 (decimal 8053) + defining Unicode char U+1F76 (decimal 8054) + defining Unicode char U+1F77 (decimal 8055) + defining Unicode char U+1F78 (decimal 8056) + defining Unicode char U+1F79 (decimal 8057) + defining Unicode char U+1F7A (decimal 8058) + defining Unicode char U+1F7B (decimal 8059) + defining Unicode char U+1F7C (decimal 8060) + defining Unicode char U+1F7D (decimal 8061) + defining Unicode char U+1F80 (decimal 8064) + defining Unicode char U+1F81 (decimal 8065) + defining Unicode char U+1F82 (decimal 8066) + defining Unicode char U+1F83 (decimal 8067) + defining Unicode char U+1F84 (decimal 8068) + defining Unicode char U+1F85 (decimal 8069) + defining Unicode char U+1F86 (decimal 8070) + defining Unicode char U+1F87 (decimal 8071) + defining Unicode char U+1F88 (decimal 8072) + defining Unicode char U+1F89 (decimal 8073) + defining Unicode char U+1F8A (decimal 8074) + defining Unicode char U+1F8B (decimal 8075) + defining Unicode char U+1F8C (decimal 8076) + defining Unicode char U+1F8D (decimal 8077) + defining Unicode char U+1F8E (decimal 8078) + defining Unicode char U+1F8F (decimal 8079) + defining Unicode char U+1F90 (decimal 8080) + defining Unicode char U+1F91 (decimal 8081) + defining Unicode char U+1F92 (decimal 8082) + defining Unicode char U+1F93 (decimal 8083) + defining Unicode char U+1F94 (decimal 8084) + defining Unicode char U+1F95 (decimal 8085) + defining Unicode char U+1F96 (decimal 8086) + defining Unicode char U+1F97 (decimal 8087) + defining Unicode char U+1F98 (decimal 8088) + defining Unicode char U+1F99 (decimal 8089) + defining Unicode char U+1F9A (decimal 8090) + defining Unicode char U+1F9B (decimal 8091) + defining Unicode char U+1F9C (decimal 8092) + defining Unicode char U+1F9D (decimal 8093) + defining Unicode char U+1F9E (decimal 8094) + defining Unicode char U+1F9F (decimal 8095) + defining Unicode char U+1FA0 (decimal 8096) + defining Unicode char U+1FA1 (decimal 8097) + defining Unicode char U+1FA2 (decimal 8098) + defining Unicode char U+1FA3 (decimal 8099) + defining Unicode char U+1FA4 (decimal 8100) + defining Unicode char U+1FA5 (decimal 8101) + defining Unicode char U+1FA6 (decimal 8102) + defining Unicode char U+1FA7 (decimal 8103) + defining Unicode char U+1FA8 (decimal 8104) + defining Unicode char U+1FA9 (decimal 8105) + defining Unicode char U+1FAA (decimal 8106) + defining Unicode char U+1FAB (decimal 8107) + defining Unicode char U+1FAC (decimal 8108) + defining Unicode char U+1FAD (decimal 8109) + defining Unicode char U+1FAE (decimal 8110) + defining Unicode char U+1FAF (decimal 8111) + defining Unicode char U+1FB0 (decimal 8112) + defining Unicode char U+1FB1 (decimal 8113) + defining Unicode char U+1FB2 (decimal 8114) + defining Unicode char U+1FB3 (decimal 8115) + defining Unicode char U+1FB4 (decimal 8116) + defining Unicode char U+1FB6 (decimal 8118) + defining Unicode char U+1FB7 (decimal 8119) + defining Unicode char U+1FB8 (decimal 8120) + defining Unicode char U+1FB9 (decimal 8121) + defining Unicode char U+1FBA (decimal 8122) + defining Unicode char U+1FBB (decimal 8123) + defining Unicode char U+1FBC (decimal 8124) + defining Unicode char U+1FBD (decimal 8125) + defining Unicode char U+1FBE (decimal 8126) + defining Unicode char U+1FBF (decimal 8127) + defining Unicode char U+1FC0 (decimal 8128) + defining Unicode char U+1FC1 (decimal 8129) + defining Unicode char U+1FC2 (decimal 8130) + defining Unicode char U+1FC3 (decimal 8131) + defining Unicode char U+1FC4 (decimal 8132) + defining Unicode char U+1FC6 (decimal 8134) + defining Unicode char U+1FC7 (decimal 8135) + defining Unicode char U+1FC8 (decimal 8136) + defining Unicode char U+1FC9 (decimal 8137) + defining Unicode char U+1FCA (decimal 8138) + defining Unicode char U+1FCB (decimal 8139) + defining Unicode char U+1FCC (decimal 8140) + defining Unicode char U+1FCD (decimal 8141) + defining Unicode char U+1FCE (decimal 8142) + defining Unicode char U+1FCF (decimal 8143) + defining Unicode char U+1FD0 (decimal 8144) + defining Unicode char U+1FD1 (decimal 8145) + defining Unicode char U+1FD2 (decimal 8146) + defining Unicode char U+1FD3 (decimal 8147) + defining Unicode char U+1FD6 (decimal 8150) + defining Unicode char U+1FD7 (decimal 8151) + defining Unicode char U+1FD8 (decimal 8152) + defining Unicode char U+1FD9 (decimal 8153) + defining Unicode char U+1FDA (decimal 8154) + defining Unicode char U+1FDB (decimal 8155) + defining Unicode char U+1FDD (decimal 8157) + defining Unicode char U+1FDE (decimal 8158) + defining Unicode char U+1FDF (decimal 8159) + defining Unicode char U+1FE0 (decimal 8160) + defining Unicode char U+1FE1 (decimal 8161) + defining Unicode char U+1FE2 (decimal 8162) + defining Unicode char U+1FE3 (decimal 8163) + defining Unicode char U+1FE4 (decimal 8164) + defining Unicode char U+1FE5 (decimal 8165) + defining Unicode char U+1FE6 (decimal 8166) + defining Unicode char U+1FE7 (decimal 8167) + defining Unicode char U+1FE8 (decimal 8168) + defining Unicode char U+1FE9 (decimal 8169) + defining Unicode char U+1FEA (decimal 8170) + defining Unicode char U+1FEB (decimal 8171) + defining Unicode char U+1FEC (decimal 8172) + defining Unicode char U+1FED (decimal 8173) + defining Unicode char U+1FEE (decimal 8174) + defining Unicode char U+1FEF (decimal 8175) + defining Unicode char U+1FF2 (decimal 8178) + defining Unicode char U+1FF3 (decimal 8179) + defining Unicode char U+1FF4 (decimal 8180) + defining Unicode char U+1FF6 (decimal 8182) + defining Unicode char U+1FF7 (decimal 8183) + defining Unicode char U+1FF8 (decimal 8184) + defining Unicode char U+1FF9 (decimal 8185) + defining Unicode char U+1FFA (decimal 8186) + defining Unicode char U+1FFB (decimal 8187) + defining Unicode char U+1FFC (decimal 8188) + defining Unicode char U+1FFD (decimal 8189) + defining Unicode char U+1FFE (decimal 8190) + defining Unicode char U+2013 (decimal 8211) + defining Unicode char U+2014 (decimal 8212) + defining Unicode char U+2018 (decimal 8216) + defining Unicode char U+2019 (decimal 8217) + defining Unicode char U+201A (decimal 8218) + defining Unicode char U+2030 (decimal 8240) + defining Unicode char U+2039 (decimal 8249) + defining Unicode char U+203A (decimal 8250) + defining Unicode char U+20AC (decimal 8364) + defining Unicode char U+2126 (decimal 8486) + defining Unicode char U+10144 (decimal 65860) + defining Unicode char U+10145 (decimal 65861) + defining Unicode char U+10146 (decimal 65862) + defining Unicode char U+10147 (decimal 65863) +) +(/usr/share/texlive/texmf-dist/tex/latex/greek-fontenc/greek-fontenc.def +File: greek-fontenc.def 2020/10/30 2.0 Common Greek font encoding definitions +)) +LaTeX Info: Redefining \& on input line 125. +)) +(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +Package: inputenc 2021/02/14 v1.3d Input encoding file +\inpenc@prehook=\toks16 +\inpenc@posthook=\toks17 +) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2021/10/15 v2.17l AMS math features +\@mathmargin=\skip50 + +For additional information on amsmath, use the `?' option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2021/08/26 v2.01 AMS text + +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks18 +\ex@=\dimen140 +)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen141 +) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 2021/08/26 v2.02 operator names +) +\inf@bad=\count198 +LaTeX Info: Redefining \frac on input line 234. +\uproot@=\count199 +\leftroot@=\count266 +LaTeX Info: Redefining \overline on input line 399. +\classnum@=\count267 +\DOTSCASE@=\count268 +LaTeX Info: Redefining \ldots on input line 496. +LaTeX Info: Redefining \dots on input line 499. +LaTeX Info: Redefining \cdots on input line 620. +\Mathstrutbox@=\box50 +\strutbox@=\box51 +\big@size=\dimen142 +LaTeX Font Info: Redeclaring font encoding OML on input line 743. +LaTeX Font Info: Redeclaring font encoding OMS on input line 744. +\macc@depth=\count269 +\c@MaxMatrixCols=\count270 +\dotsspace@=\muskip16 +\c@parentequation=\count271 +\dspbrk@lvl=\count272 +\tag@help=\toks19 +\row@=\count273 +\column@=\count274 +\maxfields@=\count275 +\andhelp@=\toks20 +\eqnshift@=\dimen143 +\alignsep@=\dimen144 +\tagshift@=\dimen145 +\tagwidth@=\dimen146 +\totwidth@=\dimen147 +\lineht@=\dimen148 +\@envbody=\toks21 +\multlinegap=\skip51 +\multlinetaggap=\skip52 +\mathdisplay@stack=\toks22 +LaTeX Info: Redefining \[ on input line 2938. +LaTeX Info: Redefining \] on input line 2939. +) +(/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty +Package: bm 2021/04/25 v1.2e Bold Symbol Support (DPC/FMi) +\symboldoperators=\mathgroup4 +\symboldletters=\mathgroup5 +\symboldsymbols=\mathgroup6 +Package bm Info: No bold for \OMX/cmex/m/n, using \pmb. +LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 149. +) +(/usr/share/texlive/texmf-dist/tex/latex/chngcntr/chngcntr.sty +Package: chngcntr 2018/04/09 v1.1a change counter resetting +Package chngcntr Info: \counterwithout already defined. +(chngcntr) Quitting chngcntr on input line 21. +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks23 +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2021/03/04 v1.4d Standard LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2021/08/11 v1.11 sin cos tan (DPC) +) +(/usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/graphics.cfg +File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration +) +Package graphics Info: Driver file: pdftex.def on input line 107. + +(/usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def +File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex +)) +\Gin@req@height=\dimen149 +\Gin@req@width=\dimen150 +) +(/usr/share/texlive/texmf-dist/tex/latex/caption/subcaption.sty +Package: subcaption 2020/10/07 v1.3j Sub-captions (AR) + +(/usr/share/texlive/texmf-dist/tex/latex/caption/caption.sty +Package: caption 2020/10/26 v3.5g Customizing captions (AR) + +(/usr/share/texlive/texmf-dist/tex/latex/caption/caption3.sty +Package: caption3 2020/10/21 v2.2e caption3 kernel (AR) +\captionmargin=\dimen151 +\captionmargin@=\dimen152 +\captionwidth=\dimen153 +\caption@tempdima=\dimen154 +\caption@indent=\dimen155 +\caption@parindent=\dimen156 +\caption@hangindent=\dimen157 +Package caption Info: Standard document class detected. +) +\c@caption@flags=\count276 +\c@continuedfloat=\count277 +) +\c@subfigure=\count278 +\c@subtable=\count279 +) +(/usr/share/texlive/texmf-dist/tex/latex/placeins/placeins.sty +Package: placeins 2005/04/18 v 2.2 +) +(/usr/share/texlive/texmf-dist/tex/latex/tools/verbatim.sty +Package: verbatim 2020-07-07 v1.5u LaTeX2e package for verbatim enhancements +\every@verbatim=\toks24 +\verbatim@line=\toks25 +\verbatim@in@stream=\read3 +) +(/usr/share/texlive/texmf-dist/tex/latex/booktabs/booktabs.sty +Package: booktabs 2020/01/12 v1.61803398 Publication quality tables +\heavyrulewidth=\dimen158 +\lightrulewidth=\dimen159 +\cmidrulewidth=\dimen160 +\belowrulesep=\dimen161 +\belowbottomsep=\dimen162 +\aboverulesep=\dimen163 +\abovetopsep=\dimen164 +\cmidrulesep=\dimen165 +\cmidrulekern=\dimen166 +\defaultaddspace=\dimen167 +\@cmidla=\count280 +\@cmidlb=\count281 +\@aboverulesep=\dimen168 +\@belowrulesep=\dimen169 +\@thisruleclass=\count282 +\@lastruleclass=\count283 +\@thisrulewidth=\dimen170 +) +Package babel Info: Making ; an active character on input line 21. + +(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def +File: l3backend-pdftex.def 2022-01-12 L3 backend support: PDF output (pdfTeX) +\l__color_backend_stack_int=\count284 +\l__pdf_internal_box=\box52 +) +(./lab2_report.aux +LaTeX Font Info: Trying to load font information for LGR+cmr on input line 5 +. + +(/usr/share/texlive/texmf-dist/tex/latex/cbfonts-fd/lgrcmr.fd +File: lgrcmr.fd 2017/07/29 v1.2 Greek European Computer Regular +) + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + + +LaTeX Warning: Label `fig:' multiply defined. + + +LaTeX Warning: Label `sub@fig:' multiply defined. + +) +\openout1 = `lab2_report.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. +LaTeX Font Info: Checking defaults for LGR/cmr/m/n on input line 34. +LaTeX Font Info: ... okay on input line 34. + (/usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +\scratchcounter=\count285 +\scratchdimen=\dimen171 +\scratchbox=\box53 +\nofMPsegments=\count286 +\nofMParguments=\count287 +\everyMPshowfont=\toks26 +\MPscratchCnt=\count288 +\MPscratchDim=\dimen172 +\MPnumerator=\count289 +\makeMPintoPDFobject=\count290 +\everyMPtoPDFconversion=\toks27 +) (/usr/share/texlive/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty +Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf +Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4 +85. + +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg +File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv +e +)) +Package caption Info: Begin \AtBeginDocument code. +Package caption Info: End \AtBeginDocument code. +LaTeX Font Info: Trying to load font information for LGR+cmtt on input line +35. + +(/usr/share/texlive/texmf-dist/tex/latex/cbfonts-fd/lgrcmtt.fd +File: lgrcmtt.fd 2017/07/29 v1.2 Greek European Computer Typewriter +) [1 + +{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./lab2_report.toc) +\tf@toc=\write3 +\openout3 = `lab2_report.toc'. + + [2 + +] +Overfull \hbox (11.23567pt too wide) in paragraph at lines 61--62 +[]\LGR/cmr/m/n/10 H su-nr-th-sh pu-knth-tac pi-ja-nth-tac ek-pai-de-e-tai q +rsei twn pa-re-qme-nwn de-do-mnwn []\OT1/cmtt/m/n/10 skinSamplesRGB.mat[]\LG +R/cmr/m/n/10 . + [] + +<../part1/results/binary_skin_image.png, id=16, 462.528pt x 346.896pt> +File: ../part1/results/binary_skin_image.png Graphic file (type png) + +Package pdftex.def Info: ../part1/results/binary_skin_image.png used on input +line 79. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/results/binary_skin_image_better.png, id=18, 462.528pt x 346.896pt> +File: ../part1/results/binary_skin_image_better.png Graphic file (type png) + +Package pdftex.def Info: ../part1/results/binary_skin_image_better.png used on + input line 86. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/results/skin_detection_1.png, id=19, 462.528pt x 346.896pt> +File: ../part1/results/skin_detection_1.png Graphic file (type png) + +Package pdftex.def Info: ../part1/results/skin_detection_1.png used on input l +ine 103. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/results/skin_detection_16.png, id=20, 462.528pt x 346.896pt> +File: ../part1/results/skin_detection_16.png Graphic file (type png) + +Package pdftex.def Info: ../part1/results/skin_detection_16.png used on input +line 110. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/results/skin_detection_26.png, id=21, 462.528pt x 346.896pt> +File: ../part1/results/skin_detection_26.png Graphic file (type png) + +Package pdftex.def Info: ../part1/results/skin_detection_26.png used on input +line 117. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/results/skin_detection_36.png, id=22, 462.528pt x 346.896pt> +File: ../part1/results/skin_detection_36.png Graphic file (type png) + +Package pdftex.def Info: ../part1/results/skin_detection_36.png used on input +line 124. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +[3 + + <../part1/results/binary_skin_image.png> <../part1/results/binary_skin_image_b +etter.png>] [4 <../part1/results/skin_detection_1.png> <../part1/results/skin_d +etection_16.png> <../part1/results/skin_detection_26.png> <../part1/results/ski +n_detection_36.png>] +<../part1/flow/n_16.png, id=47, 462.528pt x 346.896pt> +File: ../part1/flow/n_16.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/n_16.png used on input line 162. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow/n_26.png, id=48, 462.528pt x 346.896pt> +File: ../part1/flow/n_26.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/n_26.png used on input line 169. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow/n_36.png, id=49, 462.528pt x 346.896pt> +File: ../part1/flow/n_36.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/n_36.png used on input line 179. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow/n_46.png, id=50, 462.528pt x 346.896pt> +File: ../part1/flow/n_46.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/n_46.png used on input line 186. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[5 + + <../part1/flow/n_16.png> <../part1/flow/n_26.png>] [6 <../part1/flow/n_36.png> + <../part1/flow/n_46.png>] +<../part1/flow/16.png, id=62, 462.528pt x 346.896pt> +File: ../part1/flow/16.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/16.png used on input line 206. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow/26.png, id=63, 462.528pt x 346.896pt> +File: ../part1/flow/26.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/26.png used on input line 213. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow/36.png, id=64, 462.528pt x 346.896pt> +File: ../part1/flow/36.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/36.png used on input line 223. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow/46.png, id=65, 462.528pt x 346.896pt> +File: ../part1/flow/46.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow/46.png used on input line 230. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. + [7 + + <../part1/flow/16.png> <../part1/flow/26.png> <../part1/flow/36.png> <../part1 +/flow/46.png>] +<../part1/flow_multiscale/n_16.png, id=74, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/n_16.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/n_16.png used on input line +248. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow_multiscale/n_26.png, id=75, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/n_26.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/n_26.png used on input line +255. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow_multiscale/n_36.png, id=76, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/n_36.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/n_36.png used on input line +265. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow_multiscale/n_46.png, id=77, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/n_46.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/n_46.png used on input line +272. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. + [8 + + <../part1/flow_multiscale/n_16.png> <../part1/flow_multiscale/n_26.png> <../pa +rt1/flow_multiscale/n_36.png> <../part1/flow_multiscale/n_46.png>] +<../part1/flow_multiscale/16.png, id=85, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/16.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/16.png used on input line 28 +9. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow_multiscale/26.png, id=86, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/26.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/26.png used on input line 29 +6. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow_multiscale/36.png, id=87, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/36.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/36.png used on input line 30 +6. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. +<../part1/flow_multiscale/46.png, id=88, 462.528pt x 346.896pt> +File: ../part1/flow_multiscale/46.png Graphic file (type png) + +Package pdftex.def Info: ../part1/flow_multiscale/46.png used on input line 31 +3. +(pdftex.def) Requested size: 230.18253pt x 172.63771pt. + [9 <../part1/flow_multiscale/16.png> <../part1/flow_multiscale/26.png> <../par +t1/flow_multiscale/36.png> <../part1/flow_multiscale/46.png>] [10 + +] [11 + +] (./lab2_report.aux) + +LaTeX Warning: There were multiply-defined labels. + + ) +Here is how much of TeX's memory you used: + 6033 strings out of 480171 + 104503 string characters out of 5894490 + 398107 words of memory out of 5000000 + 23891 multiletter control sequences out of 15000+600000 + 486735 words of font info for 73 fonts, out of 8000000 for 9000 + 59 hyphenation exceptions out of 8191 + 67i,16n,77p,1109b,484s stack positions out of 5000i,500n,10000p,200000b,80000s + + +Output written on lab2_report.pdf (11 pages, 3849317 bytes). +PDF statistics: + 185 PDF objects out of 1000 (max. 8388607) + 87 compressed objects within 1 object stream + 0 named destinations out of 1000 (max. 500000) + 111 words of extra memory for PDF output out of 10000 (max. 10000000) + diff --git a/lab2/report/lab2_report.pdf b/lab2/report/lab2_report.pdf new file mode 100644 index 0000000..990610c Binary files /dev/null and b/lab2/report/lab2_report.pdf differ diff --git a/lab2/report/lab2_report.tex b/lab2/report/lab2_report.tex new file mode 100644 index 0000000..99d4ae3 --- /dev/null +++ b/lab2/report/lab2_report.tex @@ -0,0 +1,329 @@ +\documentclass{article} +\usepackage{fullpage} +\usepackage[english,greek, main=greek]{babel} +\usepackage[utf8]{inputenc} + +\usepackage{amsmath} +\usepackage{bm} +\usepackage{chngcntr} +\counterwithin{equation}{section} + +\usepackage{graphicx} +\usepackage{subcaption} +\usepackage{placeins} + +\usepackage{verbatim} +\usepackage{booktabs} + +\newcommand{\eng}[1]{\foreignlanguage{english}{#1}} +\newcommand{\Alpha}{\mathrm{A}} + +\useshorthands{;} +\defineshorthand{;}{?} + +\title{Όραση Υπολογιστών\\ +\large Εργαστήριο 1} +\author{Αναστάσιος Στέφανος Αναγνώστου\\ + \texttt{03119051} + \and + Σπυρίδων Παπαδόπουλος\\ +\texttt{03119058}} + +\date{7 Απριλίου 2023} + +\begin{document} +\maketitle + +\clearpage +\tableofcontents +\clearpage + +Ο κώδικας παρατίθεται σε ξεχωριστά αρχεία με επαρκή σχολιασμό και όχι στην παρούσα αναφορά. + +\section{Μέρος 1} + +Στο πρώτο μέρος του εργαστηρίου υλοποιείται σύστημα παρακολούθησης προσώπου και χεριών σε βίντεο νοηματικής γλώσσας. + +\subsection{Ανίχνευση Δέρματος Προσώπου και Χεριών} + +Η ανίχνευση δέρματος προσώπου και χεριών επιτυγχάνεται χρήσει ενός πιθανοτικού ανιχνευτή ανθρωπίνου δέρματος. Συγκεκριμένα, θεωρείται ότι το χρώμα του δέρματος μοντελοποιείται με μία διδιάστατη Γκαουσιανή κατανομή. + +\begin{equation} + P(\pmb{c} = skin) = \frac{1}{\sqrt{\left| \Sigma \right| (2\pi)^2}}e^{-\frac{1}{2}(\pmb{c}-\pmb{\mu}) \Sigma^{-1}(\pmb{c}-\pmb{\mu})^{T}} +\end{equation} + +Το διάνυσμα τιμών $\vec{c}$ της κατανομής είναι οι διαστάσεις $C_b, C_r$ του χρωματικού χώρου \eng{YCbCr}, δηλαδή: + +\begin{equation} + \pmb{c} = \begin{bmatrix} C_b & C_r \end{bmatrix}^{T} +\end{equation} + +Η συνάρτηση πυκνότητας πιθανότητας εκπαιδεύεται χρήσει των παρεχόμενων δεδομένων \texttt{\eng{skinSamplesRGB.mat}}. Φυσικά, προτού χρησιμοποιηθούν, πρέπει να μετασχηματιστούν από τον χώρο \eng{RGB} στον χώρο \eng{YCbCr}. Αφού εκπαιδευτεί η συνάρτηση πυκνότητας πιθανότητας, η δυαδική εικόνα ανίχνευσης δέρματος προκύπτει, με κατάλληλη κατωφλιοποίηση, ως: + +\begin{equation} + \begin{gathered} + I(x, y) = + \begin{cases} + 1, \underset{x, y}{\arg} \left\{P(\pmb{c}(x, y) = skin)\ge \theta\right\} \\ + 0, \text{ειδάλλως} + \end{cases} + \end{gathered} +\end{equation} + +Σε αυτό το σημείο, η δυαδική εικόνα έχει μερικά κενά, τα οποία είναι ανεπιθύμητα, αφού είναι γνωστό ότι οι περιοχές δέρματος είναι συνεχείς. Αυτό επαληθεύεται από την ακόλουθη εικόνα \ref{fig:binary-skin-bad}. + +\begin{figure*}[h] + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/results/binary_skin_image.png} + \caption{Η ατελής δυαδική εικόνα δέρματος} + \label{fig:binary-skin-bad} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/results/binary_skin_image_better.png} + \caption{Η βελτιωμένη δυαδική εικόνα δέρματος} + \label{fig:binary-skin-good} + \end{subfigure} +\end{figure*} + + +Για την εξάλειψη των κενών, εφαρμόζεται \eng{opening} με ένα πολύ μικρό δομικό στοιχείο και \eng{closing} με ένα μεγαλύτερο ($\times 6$) δομικό στοιχείο. Το αποτέλεσμα παρατίθεται στην εικόνα \ref{fig:binary-skin-good}. + +Παρατηρείται ότι οι περιοχές είναι τώρα συνεχείς και η απεικόνιση σαφώς βελτιωμένη, με τίμημα την ακρίβεια σε οριακές περιοχές όπως είναι τα δάχτυλα. + +Τέλος, θα δημιουργηθούν ορθογώνια τα οποία περιβάλλουν τις περιοχές ενδιαφέροντος. Παρουσιάζονται ενδεικτικά μερικά πλαίσια από το βίντεο στην εικόνα \ref{fig:skin-detection}. + +\begin{figure*} + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/results/skin_detection_1.png} + \caption{Πλαίσιο 1} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/results/skin_detection_16.png} + \caption{Πλαίσιο 16} + \label{fig:} + \end{subfigure} + \vskip\baselineskip + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/results/skin_detection_26.png} + \caption{Πλαίσιο 26} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/results/skin_detection_36.png} + \caption{Πλαίσιο 36} + \label{fig:} + \end{subfigure} + \caption{Ενδεικτικός εντοπισμός δέρματος σε μερικά πλαίσια} + \label{fig:skin-detection} +\end{figure*} +\FloatBarrier + +Φαίνεται, ότι τα αποτελέσματα είναι αρκετά ικανοποιητικά. Συγκεκριμένα, οι περιοχές εντοπίζονται με αρκετή ακρίβεια σε όλες τις περιπτώσεις και τα χέρια παρακολουθούνται επιτυχώς, παρότι κινούνται και αλλάζουν το σχήματος. Μάλιστα, όπως αλλάζει το φαινόμενο μέγεθος των χεριών, αλλάζει μαζί και το περιβάλλον κουτί. + + +\clearpage +\subsection{Παρακολούθηδη Προσώπου και Χεριών} + +Σε αυτό το σημείο θα επιχειρηθεί η παρακολούθηση του προσώπου και των χεριών, όχι όμως μέσω ανίχνευσης δέρματος, αλλά μέσω εκτίμησης οπτικής ροής. Αντί, δηλαδή, να βρίσκεται σε καθένα πλαίσιο εκ νέου η περιοχή γύρω από το δέρμα, γίνεται μία εκτίμηση της οπτικής ροής από πλαίσιο σε πλαίσιο. + +\subsubsection{Υλοποίηση Αλγορίθμου \eng{Lucas-Kanade}} + +Η εκτίμηση της οπτικής ροής, εν προκειμένω, θα γίνει χρήσει του αλγορίθμου \eng{Lucas-Kanade}. Κατά τον αλγόριθμο αυτόν, υπολογίζεται η οπτική ροή καθενός σημείου της εικόνας, χρήσει της μεθόδου ελαχίστων τετραγώνων, υπό την παραδοχή ότι αυτή παραμένει σταθερή σε μία μικρή περιοχή γύρω από το σημείο. + +\begin{equation} + \begin{gathered} + I_n(\pmb{x}) \approx I_{n-1}(\pmb{x+d})\overset{\text{\eng{Taylor}}}{\Rightarrow} \\ + I_{n-1}(\pmb{x+d}) \approx I_{n-1}(\pmb{x+d_i}) + \nabla I_{n-1}(\pmb{x+d_i})^{T}\pmb{u} + \end{gathered} +\end{equation} + +Ελαχιστοποιώντας το τετραγωνικό σφάλμα, προκύπτει ένα σύστημα το οποίο προσδιορίζει πλήρως την βελτίωση της εκτίμησης της οπτικής ροής. + +Ο αλγόριθμος δεν εφαρμόζεται σε κάθε σημείο της εικόνας, αλλά αποδεικνύεται (απλώς κοιτάζοντας το προκύπτον σύστημα) ότι δίνει την βέλτιστη εκτίμηση όταν εφαρμόζεται σε γωνίες. Επομένως, πρώτα γίνεται εντοπισμός γωνιών στην εικόνα και έπειτα εφαρμόζεται ο αλγόριθμος. Η εφαρμογή γίνεται επαναληπτικά ανά σημείο, μέχρις ότου, είτε δύο διαδοχικές βελτιώσεις να διαφέρουν κατά αμελητέο ποσό, είτε να ξεπεραστεί κάποιο όριο επαναλήψεων. + +Παρατίθενται ενδεικτικά πλαίσια για την αξιολόγηση της μεθόδου στην εικόνα \ref{fig:tracking1}. Σημειώνεται, επίσης, ότι στα αρχεία της αναφοράς δίνεται το αποτέλεσμα της συνένωσης όλων των πλαισίων σε μορφή \texttt{\eng{gif}}. + +\begin{figure*}[h] + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering{} + \includegraphics[width=\textwidth]{../part1/flow/n_16.png} + \caption{Πλαίσιο 16} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow/n_26.png} + \caption{Πλαίσιο 26} + \label{fig:} + \end{subfigure} + \caption{Ενδεικτικός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής} + \label{fig:tracking1} +\end{figure*} +\begin{figure*}[h] + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow/n_36.png} + \caption{Πλαίσιο 36} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow/n_46.png} + \caption{Πλαίσιο 46} + \label{fig:} + \end{subfigure} + \caption{Ενδεικτικός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής} + \label{fig:tracking2} +\end{figure*} +\FloatBarrier + +Επισκοπώντας τα αποτελέσματα, συμπεραίνεται, ότι η εκτίμηση της οπτικής ροής λειτουργεί αρκετά καλά για μικρές, αργές κινήσεις. Αυτό επαληθεύεται από τα 3 πρώτα παρατιθέμενα πλαίσια, στα οποία οι κινήσεις ήταν αργές και ομαλές. Ωστόσο, όταν οι κινήσεις γίνονται απότομες, η αποδοτικότητα του αλγορίθμου μειώνεται, με αποτέλεσμα να υστερούν τα κουτιά από τις περιοχές ενδιαφέροντος, όπως φαίνεται στο τελευταίο πλαίσιο. Σημειώνεται, επίσης, ότι η κλίμακα του κουτιού δεν αλλάζει, όπως προηγουμένως, αλλά παραμένει σταθερή. + +\clearpage +\subsubsection{Υπολογισμός Μετατόπισης Παραθύρων και Οπτικής Ροής} + +Το συνολικό διάνυσμα μετατόπισης του κουτιού βρίσκεται, ουσιαστικά, υπολογίζοντας έναν απλό μέσον όρο. Συγκεκριμένα, υπολογίζεται ο μέσος όρος των διανυσμάτων μετατόπισης αυτών, τα οποία έχουν ενέργεια $\left|\left| \pmb{d}^2 \right|\right| = d_x^2 + dy^2$ μεγαλύτερη από ένα κατώφλι, ώστε να απορριφθούν \eng{outliers} και να επιτευχθεί καλύτερη ακρίβεια. + +\begin{figure*}[h] + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering{} + \includegraphics[width=\textwidth]{../part1/flow/16.png} + \caption{Πλαίσιο 16} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow/26.png} + \caption{Πλαίσιο 26} + \label{fig:} + \end{subfigure} + \caption{Εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια} + \label{fig:flows1} +\end{figure*} +\begin{figure*}[h] + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow/36.png} + \caption{Πλαίσιο 36} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow/46.png} + \caption{Πλαίσιο 46} + \label{fig:} + \end{subfigure} + \caption{Εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια} + \label{fig:flows2} +\end{figure*} + + +\clearpage +\subsubsection{Πολυ-κλιμακωτός Υπολογισμός Οπτικής Ροής} + +Η κακή επίδοση του αλγορίθμου στις απότομες δημιουργεί την ανάγκη επέκτασής του σε περισσότερες κλίμακες. Συγκεκριμένα, η πολυκλιμακωτή εκδοχή του, αναλύει την αρχική εικόνα σε μία Γκαουσιανή πυραμίδα εικόνων, στο καθένα επίπεδο της οποίας βρίσκεται μία υποδειγματοληπτημένη εκδοχή της αυθεντικής εικόνας. Σε καθεμία κλίμακα χρησιμοποιείται ο αυθεντικός αλγόριθμος και μεταφέρει την εκτίμησή του στην αμέσως ανώτερη κλίμακα, προσαρμόζοντάς την κατάλληλα. Σημειώνεται, ότι τα χαρακτηριστικά πρέπει τώρα να εξαχθούν για κάθε επίπεδο της κλίμακας, όχι μόνο για την αρχική εικόνα. + +\begin{figure*}[h] + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering{} + \includegraphics[width=\textwidth]{../part1/flow_multiscale/n_16.png} + \caption{Πλαίσιο 16} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow_multiscale/n_26.png} + \caption{Πλαίσιο 26} + \label{fig:} + \end{subfigure} + \caption{Ενδεικτικός πολυκλιμακωτός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής} + \label{fig:tracking_multiscale1} +\end{figure*} +\begin{figure*}[h] + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow_multiscale/n_36.png} + \caption{Πλαίσιο 36} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow_multiscale/n_46.png} + \caption{Πλαίσιο 46} + \label{fig:} + \end{subfigure} + \caption{Ενδεικτικός πολυκλιμακωτός εντοπισμός δέρματος χρήσει εκτίμησης οπτικής ροής} + \label{fig:tracking_multiscale2} +\end{figure*} +\FloatBarrier + +Παρατηρείται, ότι σε κάθε πλαίσιο ο εντοπισμός είναι ακριβέστερος. Η διαφορά είναι ιδιαίτερα αξιοσημειώτη στο τελευταίο παρατιθέμενο πλαίσιο, όπου το μπλε κουτί περικυκλώνει τέλεια το αριστερό χέρι, ενώ στην μονοκλιμακωτή εκδοχή το έχανε λόγω ταχύτητας. + +Παρακάτω δίνονται τα αντίστοιχα αποτελέσματα για την απεικόνιση της οπτικής ροής. Η βελτίωση της ποιότητας είναι ορατή και εκεί, αφού τα διανύσματα οπτικής ροής είναι πλέον πολύ ομοιόμορφα και όλα σαφώς προσανατολισμένα προς κάποια κατεύθυνση, σε αντίθεση με την προηγούμενη μέθοδο όπου υπήρχαν κάποιες διακυμάνσεις. + +\begin{figure*}[h] + \centering + \begin{subfigure}[b]{0.49\textwidth} + \centering{} + \includegraphics[width=\textwidth]{../part1/flow_multiscale/16.png} + \caption{Πλαίσιο 16} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow_multiscale/26.png} + \caption{Πλαίσιο 26} + \label{fig:} + \end{subfigure} + \caption{Πολυκλιμακωτός εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια} + \label{fig:flow_multiscales1} +\end{figure*} +\begin{figure*}[h] + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow_multiscale/36.png} + \caption{Πλαίσιο 36} + \label{fig:} + \end{subfigure} + \hfill + \begin{subfigure}[b]{0.49\textwidth} + \centering + \includegraphics[width=\textwidth]{../part1/flow_multiscale/46.png} + \caption{Πλαίσιο 46} + \label{fig:} + \end{subfigure} + \caption{Πολυκλιμακωτός εντοπισμός δέρματος και οπτική ροή σε μερικά πλαίσια} + \label{fig:flow_multiscales2} +\end{figure*} + +\clearpage +\section{Μέρος 2} + + +\clearpage +\section{Μέρος 3} + + +\end{document} diff --git a/lab2/report/lab2_report.toc b/lab2/report/lab2_report.toc new file mode 100644 index 0000000..023d3d9 --- /dev/null +++ b/lab2/report/lab2_report.toc @@ -0,0 +1,9 @@ +\babel@toc {greek}{}\relax +\contentsline {section}{\numberline {1}Μέρος 1}{3}{}% +\contentsline {subsection}{\numberline {1.1}Ανίχνευση Δέρματος Προσώπου και Χεριών}{3}{}% +\contentsline {subsection}{\numberline {1.2}Παρακολούθηδη Προσώπου και Χεριών}{5}{}% +\contentsline {subsubsection}{\numberline {1.2.1}Υλοποίηση Αλγορίθμου \foreignlanguage {english}{Lucas-Kanade}}{5}{}% +\contentsline {subsubsection}{\numberline {1.2.2}Υπολογισμός Μετατόπισης Παραθύρων και Οπτικής Ροής}{7}{}% +\contentsline {subsubsection}{\numberline {1.2.3}Πολυ-κλιμακωτός Υπολογισμός Οπτικής Ροής}{8}{}% +\contentsline {section}{\numberline {2}Μέρος 2}{10}{}% +\contentsline {section}{\numberline {3}Μέρος 3}{11}{}%