From ccf2414cf3d02c6cec5ebb8a11ce68f2e91eb245 Mon Sep 17 00:00:00 2001 From: Abdullah Ranginwala Date: Sun, 19 Mar 2023 05:38:58 +0530 Subject: [PATCH] Updated edge-detection operators and added functionality --- imagelab_electron/imagelab-blocks.js | 55 +++++++++---------- imagelab_electron/index.html | 16 ++---- imagelab_electron/operations.js | 5 +- imagelab_electron/src/controller/main.js | 24 ++++++++ .../src/operator/edgeDetection/CannyEdge.js | 43 +++++++++++++++ .../src/operator/edgeDetection/Laplacian.js | 37 +++++++++++++ .../edgeDetection/ScharrDerivative.js | 47 ++++++++++++++++ .../operator/edgeDetection/SobleDerivative.js | 53 ++++++++++++++++++ 8 files changed, 238 insertions(+), 42 deletions(-) create mode 100644 imagelab_electron/src/operator/edgeDetection/CannyEdge.js create mode 100644 imagelab_electron/src/operator/edgeDetection/Laplacian.js create mode 100644 imagelab_electron/src/operator/edgeDetection/ScharrDerivative.js create mode 100644 imagelab_electron/src/operator/edgeDetection/SobleDerivative.js diff --git a/imagelab_electron/imagelab-blocks.js b/imagelab_electron/imagelab-blocks.js index 8bd49e6..236c7d2 100644 --- a/imagelab_electron/imagelab-blocks.js +++ b/imagelab_electron/imagelab-blocks.js @@ -1002,9 +1002,9 @@ Blockly.defineBlocksWithJsonArray([ helpUrl: "", }, - //Sobel Derivatives + //Edge Detection { - type: "sobelderivatives_soblederivate", + type: "edgedetection_soblederivate", message0: "Apply %1 sobel derivative with %2 depth", args0: [ { @@ -1028,11 +1028,11 @@ Blockly.defineBlocksWithJsonArray([ nextStatement: null, colour: 345, tooltip: - "This operator allows you to detect edges of an image of both horizontal and vertaical direction Moreover it is a first order derivative.", + "This operator allows you to detect edges of an image of both horizontal and vertical direction. Moreover it is a first order derivative.", helpUrl: "", }, { - type: "sobelderivatives_scharrderivate", + type: "edgedetection_scharrderivate", message0: "Apply %1 scharr derivative with %2 depth", args0: [ { @@ -1055,26 +1055,13 @@ Blockly.defineBlocksWithJsonArray([ nextStatement: null, colour: 345, tooltip: - "This operator allows you to detect edges of an image in both horizontal and vertaical direction. Moreover it is a second order derivative.", + "This operator allows you to detect edges of an image in both horizontal and vertical direction. Moreover it is a second order derivative.", helpUrl: "", }, - - //Transformation { - type: "transformation_distance", - message0: "Apply %1 distance with %2 depth", + type: "edgedetection_laplacian", + message0: "Apply laplacian with %1 depth", args0: [ - { - type: "field_dropdown", - name: "type", - options: [ - ["DISTC", "DIST_C"], - ["DISTL1", "DIST_L1"], - ["DISTL2", "DIST_L2"], - ["DISTLABEL_PIXEL", "DIST_LABEL_PIXEL"], - ["DISTMASK_3", "DIST_MASK_3"], - ], - }, { type: "field_number", name: "ddepth", @@ -1085,28 +1072,36 @@ Blockly.defineBlocksWithJsonArray([ ], previousStatement: null, nextStatement: null, - colour: 195, + colour: 345, tooltip: - "Distance Transformation generally takes binary images as inputs. In this operation,the gray level intensities of the points inside the foreground regions are chnaged to distance their respective distances from the closest 0 value.", + "Laplacian Transformation is also a derivate which used to find edges in an image.It is a second order derivate mask Moreover in this mask two classifications one is Postive Laplacian and Negative Laplacian Unlike other opertors Laplacian didn't take out edges in any particular direction but it takes out edges in inward edges and outward edges.", helpUrl: "", }, { - type: "transformation_laplacian", - message0: "Apply laplacian with %1 depth", + type: "edgedetection_cannyedge", + message0: "Apply canny edge with %1 aperture size, %2 minThreshold and %3 maxThreshold", args0: [ { type: "field_number", - name: "ddepth", - value: 0, - min: -10, - max: 10, + name: "aperture", + value: 3, + }, + { + type: "field_number", + name: "minThreshold", + value: 50, + }, + { + type: "field_number", + name: "maxThreshold", + value: 100, }, ], previousStatement: null, nextStatement: null, - colour: 195, + colour: 345, tooltip: - "Laplacian Transformation is also a derivate which used to find edges in an image.It is a second order derivate mask Moreover in this mask two classifications one is Postive Laplacian and Negative Laplacian Unlike other opertors Laplacian didn't take out edges in any particular direction but it takes out edges in inward edges and outward edges.", + "Canny edge detection has the ability to accurately detect edges while minimizing noise and false detections.", helpUrl: "", }, ]); diff --git a/imagelab_electron/index.html b/imagelab_electron/index.html index 37bdbad..3bdc23c 100644 --- a/imagelab_electron/index.html +++ b/imagelab_electron/index.html @@ -161,19 +161,13 @@ - - - - - - + + + + diff --git a/imagelab_electron/operations.js b/imagelab_electron/operations.js index 43d40ed..a68a2ea 100644 --- a/imagelab_electron/operations.js +++ b/imagelab_electron/operations.js @@ -20,7 +20,10 @@ const PROCESS_OPERATIONS = { PYRAMIDDOWN: "filtering_pyramiddown", EROSION: "filtering_erosion", DILATION: "filtering_dilation", - MORPHOLOGICAL: "filtering_morphological", + SOBLEDERIVATE: "edgedetection_soblederivate", + SCHARRDERIVATE: "edgedetection_scharrderivate", + LAPLACIAN: "edgedetection_laplacian", + CANNYEDGE: "edgedetection_cannyedge", }; module.exports = PROCESS_OPERATIONS; diff --git a/imagelab_electron/src/controller/main.js b/imagelab_electron/src/controller/main.js index 2afe87e..d000552 100644 --- a/imagelab_electron/src/controller/main.js +++ b/imagelab_electron/src/controller/main.js @@ -10,6 +10,10 @@ const DrawEllipse = require("../operator/drawing/DrawEllipse"); const DrawLine = require("../operator/drawing/DrawLine"); const DrawRectangle = require("../operator/drawing/DrawRectangle"); const DrawText = require("../operator/drawing/DrawText"); +const CannyEdge = require("../operator/edgeDetection/CannyEdge"); +const Laplacian = require("../operator/edgeDetection/Laplacian"); +const ScharrDerivative = require("../operator/edgeDetection/ScharrDerivative"); +const SobleDerivative = require("../operator/edgeDetection/SobleDerivative"); const BilateralFilter = require("../operator/filtering/BilateralFilter"); const BoxFilter = require("../operator/filtering/BoxFilter"); const Dilation = require("../operator/filtering/Dilation"); @@ -209,6 +213,26 @@ class MainController { new Morphological(PROCESS_OPERATIONS.MORPHOLOGICAL, id) ); break; + case PROCESS_OPERATIONS.SOBLEDERIVATE: + this.#appliedOperators.push( + new SobleDerivative(PROCESS_OPERATIONS.SOBLEDERIVATE, id) + ); + break; + case PROCESS_OPERATIONS.SCHARRDERIVATE: + this.#appliedOperators.push( + new ScharrDerivative(PROCESS_OPERATIONS.SCHARRDERIVATE, id) + ); + break; + case PROCESS_OPERATIONS.LAPLACIAN: + this.#appliedOperators.push( + new Laplacian(PROCESS_OPERATIONS.LAPLACIAN, id) + ); + break; + case PROCESS_OPERATIONS.CANNYEDGE: + this.#appliedOperators.push( + new CannyEdge(PROCESS_OPERATIONS.CannyEdge, id) + ); + break; default: break; } diff --git a/imagelab_electron/src/operator/edgeDetection/CannyEdge.js b/imagelab_electron/src/operator/edgeDetection/CannyEdge.js new file mode 100644 index 0000000..2314797 --- /dev/null +++ b/imagelab_electron/src/operator/edgeDetection/CannyEdge.js @@ -0,0 +1,43 @@ +const OpenCvOperator = require("../OpenCvOperator"); + + /** + * This class contains the main logic to add Canny Edge + * to an image + */ + + class CannyEdge extends OpenCvOperator { + #aperture = 3; + #minThreshold = 50; + #maxThreshold = 100; + constructor(type, id) { + super(type, id); + } + + setParams(type, value) { + if (type === "aperture") { + this.#aperture = value; + } else if (type === "minThreshold") { + this.#minThreshold = value; + } else if (type === "maxThreshold") { + this.#maxThreshold = value; + } + } + + + /** + * + * @param {Mat} image + * @returns + * + * This function processes Canny Edge + * to the mat image + */ + compute(image) { + const dst = new this.cv2.Mat(); + this.cv2.cvtColor(image, image, this.cv2.COLOR_RGB2GRAY, 0); + this.cv2.Canny(image, dst, this.#minThreshold, this.#maxThreshold, this.#aperture, false); + return dst; + } + } + + module.exports = CannyEdge; \ No newline at end of file diff --git a/imagelab_electron/src/operator/edgeDetection/Laplacian.js b/imagelab_electron/src/operator/edgeDetection/Laplacian.js new file mode 100644 index 0000000..1bf7cfc --- /dev/null +++ b/imagelab_electron/src/operator/edgeDetection/Laplacian.js @@ -0,0 +1,37 @@ +const OpenCvOperator = require("../OpenCvOperator"); + + /** + * This class contains the main logic to add Laplacian + * to an image + */ + + class Laplacian extends OpenCvOperator { + #ddepth = 0; + constructor(type, id) { + super(type, id); + } + + setParams(type, value) { + if (type === "ddepth") { + this.#ddepth = value; + } + } + + + /** + * + * @param {Mat} image + * @returns + * + * This function processes Laplacian + * to the mat image + */ + compute(image) { + const dst = new this.cv2.Mat(); + this.cv2.cvtColor(image, image, this.cv2.COLOR_RGB2GRAY, 0); + this.cv2.Laplacian(image, dst, this.#ddepth, 3, 1, 0, this.cv2.BORDER_DEFAULT); + return dst; + } + } + + module.exports = Laplacian; \ No newline at end of file diff --git a/imagelab_electron/src/operator/edgeDetection/ScharrDerivative.js b/imagelab_electron/src/operator/edgeDetection/ScharrDerivative.js new file mode 100644 index 0000000..a8ee30c --- /dev/null +++ b/imagelab_electron/src/operator/edgeDetection/ScharrDerivative.js @@ -0,0 +1,47 @@ +const OpenCvOperator = require("../OpenCvOperator"); + + /** + * This class contains the main logic to add Scharr Derivative + * to an image + */ + + class ScharrDerivative extends OpenCvOperator { + #vertical = false; + #ddepth = 0; + constructor(type, id) { + super(type, id); + } + + setParams(type, value) { + if (type === "type") { + if(value === "VERTICAL") { + this.#vertical=true; + } else { + } + } else if (type === "ddepth") { + this.#ddepth = value; + } + } + + + /** + * + * @param {Mat} image + * @returns + * + * This function processes the Scharr Derivative + * to the mat image + */ + compute(image) { + const dst = new this.cv2.Mat(); + this.cv2.cvtColor(image, image, this.cv2.COLOR_RGB2GRAY, 0); + if(this.#vertical) { + this.cv2.Scharr(image, dst, this.#ddepth, 0, 1, 1, 0, this.cv2.BORDER_DEFAULT); + } else { + this.cv2.Scharr(image, dst, this.#ddepth, 1, 0, 1, 0, this.cv2.BORDER_DEFAULT); + } + return dst; + } + } + + module.exports = ScharrDerivative; \ No newline at end of file diff --git a/imagelab_electron/src/operator/edgeDetection/SobleDerivative.js b/imagelab_electron/src/operator/edgeDetection/SobleDerivative.js new file mode 100644 index 0000000..f6784dd --- /dev/null +++ b/imagelab_electron/src/operator/edgeDetection/SobleDerivative.js @@ -0,0 +1,53 @@ +const OpenCvOperator = require("../OpenCvOperator"); + + /** + * This class contains the main logic to add Soble Derivative + * to an image + */ + + class SobleDerivative extends OpenCvOperator { + #vertical = false; + #horizontal = false; + #ddepth = 0; + constructor(type, id) { + super(type, id); + } + + setParams(type, value) { + if (type === "type") { + if(value === "HORIZONTAL") { + this.#horizontal=true; + } else if(value === "VERTICAL") { + this.#vertical=true; + } + } else if (type === "ddepth") { + this.#ddepth = value; + } + } + + + /** + * + * @param {Mat} image + * @returns + * + * This function processes the Soble Derivative + * to the mat image + */ + + compute(image) { + const dst = new this.cv2.Mat(); + this.cv2.cvtColor(image, image, this.cv2.COLOR_RGB2GRAY, 0); + if(this.#horizontal) { + this.cv2.Sobel(image, dst, this.#ddepth, 1, 0, 3, 1, 0, this.cv2.BORDER_DEFAULT); + } else if(this.#vertical) { + this.cv2.Sobel(image, dst, this.#ddepth, 0, 1, 3, 1, 0, this.cv2.BORDER_DEFAULT); + } else { + this.cv2.Sobel(image, dst, this.#ddepth, 1, 0, 3, 1, 0, this.cv2.BORDER_DEFAULT); + this.cv2.Sobel(image, dst, this.#ddepth, 0, 1, 3, 1, 0, this.cv2.BORDER_DEFAULT); + } + return dst; + } + } + + module.exports = SobleDerivative; \ No newline at end of file