diff --git a/Backend/src/kMeans.js b/Backend/src/kMeans.js index 0fec4f7..c9df04e 100644 --- a/Backend/src/kMeans.js +++ b/Backend/src/kMeans.js @@ -1,65 +1,111 @@ -function arrayToMatrix(array, width ,height){ - var matrix = []; - var temp = []; - for(var i=0; i<=(height * width); i++){ - if(i%width == 0 && i != 0){ - matrix.push(temp) - temp = [] - } - temp.push(array[i]); +/** + * Converts a flat array into a matrix of specified width and height. + * @param {Array} array - The flat array to convert into a matrix. + * @param {number} width - The desired width of the matrix. + * @param {number} height - The desired height of the matrix. + * @returns {Array} - The matrix representation of the input array. + */ +function arrayToMatrix(array, width, height) { + var matrix = []; + var temp = []; + + // Iterate over each element in the array + for (var i = 0; i < array.length; i++) { + // Check if a new row should be created + if (i % width === 0 && i !== 0) { + // Push the current row to the matrix + matrix.push(temp); + // Reset the temporary row array + temp = []; } - return matrix; + // Add the current element to the temporary row array + temp.push(array[i]); + } + + // Push the last row to the matrix + matrix.push(temp); + + // Return the resulting matrix + return matrix; } -function getRandomPixels(matrix, K){ - l = matrix.length; - b = matrix[0].length; + +/** + * Generates random pixels from a given matrix. + * @param {Array} matrix - A two-dimensional array representing an image or pixel grid. + * @param {number} K - The number of random pixels to generate. + * @returns {Array} - An array of pixel values with a count of 1. + */ +function getRandomPixels(matrix, K) { + // Get the dimensions of the matrix + const length = matrix.length; + const breadth = matrix[0].length; + + // Array to store the random pixels let randomPixels = []; - for(let i=0; i (Math.abs(matrix[i][j] - clusters[k][0]))){ + + // Find the closest cluster value to the current pixel + for (let k = 0; k < clusters.length; k++) { + if (currentDist > Math.abs(matrix[i][j] - clusters[k][0])) { currentDist = Math.abs(matrix[i][j] - clusters[k][0]); closestValue = k; } } - - clusters[closestValue][0] = ( - Math.round(((clusters[closestValue][0] * clusters[closestValue][1])+matrix[i][j])/(clusters[closestValue][1] + 1)) - ); + + // Update the closest cluster value based on the current pixel + clusters[closestValue][0] = Math.round(((clusters[closestValue][0] * clusters[closestValue][1]) + matrix[i][j]) / (clusters[closestValue][1] + 1)); clusters[closestValue][1]++; } } - // Assigning the values to pixels - for(let i =0; i (Math.abs(matrix[i][j] - clusters[k][0]))){ + + // Find the closest cluster value to the current pixel + for (let k = 0; k < clusters.length; k++) { + if (currentDist > Math.abs(matrix[i][j] - clusters[k][0])) { currentDist = Math.abs(matrix[i][j] - clusters[k][0]); closestValue = clusters[k][0]; } } + + // Update the matrix with the closest cluster value matrix[i][j] = closestValue; } } - } - async function kMeans(K, numChannel){ const convert = require("./matrixToImage"); const { createCanvas, Image, getImageData} = require('canvas'); diff --git a/__tests__/test.js b/__tests__/test_array2matrix.js similarity index 100% rename from __tests__/test.js rename to __tests__/test_array2matrix.js diff --git a/__tests__/test_change2Closest.js b/__tests__/test_change2Closest.js new file mode 100644 index 0000000..e61206d --- /dev/null +++ b/__tests__/test_change2Closest.js @@ -0,0 +1,23 @@ +const currObject = require('../Backend/src/kMeans.js'); + +describe('changeToClosest', () => { + it('should update the matrix with the closest cluster values', () => { + // Test input + const matrix = [ + [10, 20, 30], + [40, 50, 60], + [70, 80, 90] + ]; + const K = 2; + + // Make a copy of the original matrix for comparison + const originalMatrix = JSON.parse(JSON.stringify(matrix)); + + // Call the changeToClosest function + currObject.changeToClosest(matrix, K); + + // Assertions + expect(matrix).not.toEqual(originalMatrix); + // Additional assertions based on the expected behavior of the changeToClosest function + }); + }); \ No newline at end of file diff --git a/__tests__/test_getRandom.js b/__tests__/test_getRandom.js new file mode 100644 index 0000000..28e4b22 --- /dev/null +++ b/__tests__/test_getRandom.js @@ -0,0 +1,61 @@ +const currObject = require('../Backend/src/kMeans.js'); + + +describe('getRandomPixels', () => { + it('should return an array of random pixels with the specified count', () => { + // Test input + const matrix = [ + [100, 200, 300], + [400, 500, 600], + [700, 800, 900] + ]; + const K = 5; + + // Call the getRandomPixels function + const result = currObject.getRandomPixels(matrix, K); + + // Assertions + expect(result).toHaveLength(K); + result.forEach((pixel) => { + expect(pixel).toHaveLength(2); + expect(matrix.flat()).toContain(pixel[0]); + expect(pixel[1]).toBe(1); + }); + }); + + it('should return an array of random pixels with the specified count', () => { + // Test input + const matrix = [ + [10, 20, 30], + [40, 50, 60], + [70, 80, 90] + ]; + const K = 3; + + // Call the getRandomPixels function + const result = currObject.getRandomPixels(matrix, K); + + // Assertions + expect(result).toHaveLength(K); + result.forEach((pixel) => { + expect(pixel).toHaveLength(2); + expect(matrix.flat()).toContain(pixel[0]); + expect(pixel[1]).toBe(1); + }); + }); + + it('should return an empty array when K is 0', () => { + // Test input + const matrix = [ + [10, 20], + [30, 40] + ]; + const K = 0; + + // Call the getRandomPixels function + const result = currObject.getRandomPixels(matrix, K); + + // Assertion + expect(result).toHaveLength(0); + }); +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c21a6f4..8f446ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1522,21 +1522,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/babel-jest": { "version": "29.6.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.1.tgz", @@ -2039,17 +2024,6 @@ "color-support": "bin.js" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2170,14 +2144,6 @@ "node": ">=0.10.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -2520,38 +2486,6 @@ "node": ">=8" } }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -4338,11 +4272,6 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "node_modules/pca-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pca-js/-/pca-js-1.0.2.tgz", - "integrity": "sha512-Y6a1RQ/pdNJnJq7ya9PHBW2RUXZCXDbbRpmpwclvuhOo7mttx1f80OKIQ0nPF6kCZ4a98G5TqIfRrIblk7R6Jg==" - }, "node_modules/peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", @@ -4552,11 +4481,6 @@ "node": ">= 0.10" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", diff --git a/package.json b/package.json index d667574..e32b7e7 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,13 @@ }, "devDependencies": { "nodemon": "^2.0.22" - } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/mandeep-mahra/Image-Compression.git" + }, + "bugs": { + "url": "https://github.com/mandeep-mahra/Image-Compression/issues" + }, + "homepage": "https://github.com/mandeep-mahra/Image-Compression#readme" }