[
  {
    "path": "Centroid/Centroid.py",
    "content": "import cv2\n\nimg = cv2.imread(\"signature.png\", 0)\n\nret,binary = cv2.threshold(img,10,255,cv2.THRESH_BINARY)\n\ndef findBB(im):\n    h, w = im.shape[0], im.shape[1] \n    left, top = w, h\n    right, bottom = 0, 0\n    \n    for x in xrange(h):\n        for y in xrange(w):\n            if (im[x,y] == 0):\n                right = x if x > right else right\n                left = x if x < left else left\n                bottom = y if y > bottom else bottom\n                top = y if y < top else top\n                \n    return (left, right, top, bottom)\n\ndef findCentroid(im):\n    h, w = im.shape[0], im.shape[1]\n    cx, cy, n = 0, 0, 0\n    for x in xrange(h):\n        for y in xrange(w):\n            if (im[x,y] == 0):\n                cx += x\n                cy += y\n                n += 1\n    cx /= n\n    cy /= n\n    return (cx, cy)\n\ndef divideImgIntoFour(im, cent):\n    h, w = im.shape[0], im.shape[1]\n    cx, cy = cent\n    img1 = im[0:cx, 0:cy]\n    img2 = im[0:cx, cy:w]\n    img3 = im[cx:h, 0:cy]\n    img4 = im[cx:h, cy:w]\n    return [img1, img2, img3, img4]\n\ndef calculateTransitions(im):\n    h, w = im.shape[0], im.shape[1]\n    prev = im[0,0]\n    n = 0\n    for x in range(1, h):\n        for y in range(1, w):\n            curr = im[x,y]\n            # check if the is black to white transition\n            n = n+1 if curr == 255 and prev == 0 else n\n            prev = curr\n    return n\n\nboundingBox = findBB(binary)\ncropImg = binary[boundingBox[0]:boundingBox[1], boundingBox[2]:boundingBox[3]]\ncentroid = findCentroid(cropImg)\nsegments = divideImgIntoFour(cropImg, centroid)\ntransitions = [calculateTransitions(seg) for seg in segments]\n\nprint \"Bounding Box:\", boundingBox\nprint \"Coordinates of centroid:\", centroid\nprint \"Black to white transitions (4 segments):\", transitions\n\ncv2.imshow(\"TopLeft\", segments[0])\ncv2.imwrite(\"TopLeft.png\", segments[0])\ncv2.imshow(\"TopRight\", segments[1])\ncv2.imwrite(\"TopRight.png\", segments[1])\ncv2.imshow(\"BottomLeft\", segments[2])\ncv2.imwrite(\"BottomLeft.png\", segments[2])\ncv2.imshow(\"BottomRight\", segments[3])\ncv2.imwrite(\"BottomRight.png\", segments[3])\ncv2.waitKey(0)\n\n"
  },
  {
    "path": "Connected Component Labelling/ccl4.py",
    "content": "import Image, ImageOps\nimport sys\nimport random\nimport numpy\n\n\ndef colourize(img):\n    height, width = img.shape\n\n    colors = []\n    colors.append([])\n    colors.append([])\n    color = 1\n    # Displaying distinct components with distinct colors\n    coloured_img = Image.new(\"RGB\", (width, height))\n    coloured_data = coloured_img.load()\n\n    for i in range(len(img)):\n        for j in range(len(img[0])):\n            if img[i][j] > 0:\n                if img[i][j] not in colors[0]:\n                    colors[0].append(img[i][j])\n                    colors[1].append((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))\n\n                ind = colors[0].index(img[i][j])\n                coloured_data[j, i] = colors[1][ind]\n\n    return coloured_img\n\n\ndef binarize(img_array, threshold=130):\n    for i in range(len(img_array)):\n        for j in range(len(img_array[0])):\n            if img_array[i][j] > threshold:\n                img_array[i][j] = 0\n            else:\n                img_array[i][j] = 1\n    return img_array\n\n\ndef ccl4(img_array):\n    ##### first pass #####\n    print \"starting first pass\"\n    curr_label = 1;\n    img_array = numpy.array(img_array)\n    labels = numpy.array(img_array)\n\n    # storing label conversions\n    label_conv = []\n    label_conv.append([])\n    label_conv.append([])\n\n    count = 0\n    for i in range(1, len(img_array)):\n        for j in range(1, len(img_array[0])):\n\n            if img_array[i][j] > 0:\n                label_x = labels[i][j - 1]\n                label_y = labels[i - 1][j]\n\n                if label_x > 0:\n                    # both x and y have a label\n                    if label_y > 0:\n\n                        if not label_x == label_y:\n                            labels[i][j] = min(label_x, label_y)\n                            if max(label_x, label_y) not in label_conv[0]:\n                                label_conv[0].append(max(label_x, label_y))\n                                label_conv[1].append(min(label_x, label_y))\n                            elif max(label_x, label_y) in label_conv[0]:\n                                ind = label_conv[0].index(max(label_x, label_y))\n                                if label_conv[1][ind] > min(label_x, label_y):\n                                    l = label_conv[1][ind]\n                                    label_conv[1][ind] = min(label_x, label_y)\n                                    while l in label_conv[0] and count < 100:\n                                        count += 1\n                                        ind = label_conv[0].index(l)\n                                        l = label_conv[1][ind]\n                                        label_conv[1][ind] = min(label_x, label_y)\n\n                                    label_conv[0].append(l)\n                                    label_conv[1].append(min(label_x, label_y))\n\n                        else:\n                            labels[i][j] = label_y\n                    # only x has a label\n                    else:\n                        labels[i][j] = label_x\n\n                # only y has a label\n                elif label_y > 0:\n                    labels[i][j] = label_y\n\n                # neither x nor y has a label\n                else:\n                    labels[i][j] = curr_label\n                    curr_label += 1\n\n                    ##### second pass #####\n    print \"starting second pass\"\n    count = 1\n    for idx, val in enumerate(label_conv[0]):\n\n        if label_conv[1][idx] in label_conv[0] and count < 100:\n            count += 1\n            ind = label_conv[0].index(label_conv[1][idx])\n            label_conv[1][idx] = label_conv[1][ind]\n\n    for i in range(1, len(labels)):\n        for j in range(1, len(labels[0])):\n\n            if labels[i][j] in label_conv[0]:\n                ind = label_conv[0].index(labels[i][j])\n                labels[i][j] = label_conv[1][ind]\n\n    return labels\n\n\ndef main():\n    numpy.set_printoptions(threshold=numpy.nan)\n    # Open the image\n    img = Image.open(sys.argv[1])\n\n    # Threshold the image\n    img = img.convert('L')\n    img = ImageOps.expand(img, border=1, fill='white')\n    img = numpy.array(img)\n    img = binarize(img)\n\n    \"\"\"\n    img = [ [0,0,0,0,0,0,0,0,0,0],\n            [0,1,1,0,1,1,1,0,1,0],\n            [0,1,1,0,1,0,1,0,1,0],\n            [0,1,1,1,1,0,0,0,1,0],\n            [0,0,0,0,0,0,0,0,1,0],\n            [0,1,1,1,1,0,1,0,1,0],\n            [0,0,0,0,1,0,1,0,1,0],\n            [0,1,1,1,1,0,0,0,1,0],\n            [0,1,1,1,1,0,1,1,1,0],\n            [0,0,0,0,0,0,0,0,0,0]]\n    \"\"\"\n\n    img = ccl4(img)\n\n    # Colour the image using labels\n    coloured_img = colourize(img)\n\n    # Show the coloured image\n    coloured_img.show()\n\n\nif __name__ == \"__main__\": main()\n"
  },
  {
    "path": "Gradient/gradient.py",
    "content": "from PIL import Image\r\nimport cv2\r\nimport numpy as np\r\n\r\n#Read Image in GrayScale\r\nimg_gray = cv2.imread('lena.jpg',0)               \r\nh,w = img_gray.shape[:2]\r\n\r\ngrad_img = np.asarray(img_gray)\r\n\r\nfor i in range(0,h):\r\n    for j in range(0,w-1):\r\n\r\n        #applying gradient\r\n\ta = min(img_gray[i][j+1],img_gray[i][j])\r\n\tif a == img_gray[i][j+1] :\r\n \t\ttemp_arr = img_gray[i][j] - img_gray[i][j+1]\r\n\telse :\r\n\t\ttemp_arr = img_gray[i][j+1] - img_gray[i][j]\r\n        \r\n        \r\n        grad_img[i,j] = temp_arr\r\n\r\nimg = Image.fromarray(grad_img)                              \r\nimg.save(\"gradient.jpg\")\r\n\r\n"
  },
  {
    "path": "Histogram Equalization/hist_eq.py",
    "content": "from PIL import Image\nimport matplotlib.pyplot as plt\nimport cv2\nimport numpy as np\n\nimg = cv2.imread('hist2.tif',0)\n\n#Initialize intensity values with 256 zeroes\nintensity_count = [0] * 256         \n\nheight,width = img.shape[:2]        \nN = height * width                  \n\n\t#Array for new_image\nhigh_contrast = np.zeros(img.shape) \n\nfor i in range(0,height):\n    \t\tfor j in range(0,width):\n        \t\t\tintensity_count[img[i][j]] += 1     #Find pixels count for each intensity\n\nL = 256\n\nintensity_count,total_values_used = np.histogram(img.flatten(),L,[0,L])      \npdf_list = np.ceil(intensity_count*(L-1)/img.size)                    #Calculate PDF\ncdf_list = pdf_list.cumsum()                                            \t#Calculate CDF\n\n\nfor y in range(0, height):\n    \t\tfor x in range(0, width): \n\t\t\t#Apply the new intensities in our new image\n        \t\t\thigh_contrast[y,x] = cdf_list[img[y,x]]                         \n\n\t\n#PLOT THE HISTOGRAMS\ncv2.imwrite('high_contrast.png', high_contrast)                         \n\nplt.hist(img.ravel(),256,[0,256])\nplt.xlabel('Intensity Values')\nplt.ylabel('Pixel Count')\nplt.show()\n\nplt.hist(high_contrast.ravel(),256,[0,256])\t\nplt.xlabel('Intensity Values')\nplt.ylabel('Pixel Count')\nplt.show()\n"
  },
  {
    "path": "Image Negative/negative.py",
    "content": "from PIL import Image\r\nimport cv2\r\nimport sys\r\nimport numpy as np\r\n\r\nS = 255\r\n\r\n# if in rgb\r\nif(sys.argv[2]==\"rgb\"):\r\n    # open in rgb\r\n    img = cv2.imread(sys.argv[1],cv2.IMREAD_COLOR)    \r\n    B,G,R = cv2.split(img)\r\n    B[:] = [S-x for x in B]     #inverting blue\r\n    G[:] = [S-x for x in G]     #inverting green    \r\n    R[:] = [S-x for x in R]     #inverting red\r\n\r\n    #saving image\r\n    my_img = cv2.merge((B, G, R)) \r\n    cv2.imwrite(sys.argv[1]+'_inverted.png', my_img)\r\n    cv2.imshow(sys.argv[1]+'_inverted.png', my_img)     \r\n\r\n#if in grayscale or binary\r\nelse:    \r\n    # open in grayscale\r\n    img = cv2.imread(sys.argv[1],cv2.IMREAD_GRAYSCALE) \r\n    my_img = np.array([S-x for x in img])\r\n    cv2.imwrite(sys.argv[1]+'_inverted.png', my_img)\r\n    cv2.imshow(sys.argv[1]+'_inverted.png', my_img) \r\n     \r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "Image Segmentation/Segmentation.py",
    "content": "import cv2\nimport numpy as np\n\n# Loading the image in RGB\nimg = cv2.imread(\"image.png\", 0)\n\n# Applying Gaussian blur with kernel size 7 to remove unwanted noise\nblurred_image = cv2.GaussianBlur(img,(7,7),0)\n\n# Applying Otsu's thresholding to binarize the image\nretval ,binarized_image = cv2.threshold(blurred_image,40,255,cv2.THRESH_BINARY)\n\n# Applying Closing to fill in the holes\nfilter = np.ones((3,3),np.uint8)\nclosed_image = cv2.morphologyEx(binarized_image, cv2.MORPH_CLOSE, filter)\n\n# Using connected components to label the image\nretval, markers = cv2.connectedComponents(closed_image)\n\n# Mapping the component labels to hue val\nlabel_hue = np.uint8(120*markers/np.max(markers))\nblank_ch = 255*np.ones_like(label_hue)\nlabeled_image = cv2.merge([label_hue, blank_ch, blank_ch])\n\n# changing from HSV to RGB again to show\nlabeled_image = cv2.cvtColor(labeled_image, cv2.COLOR_HSV2BGR)\n\n# background label set to black\nlabeled_image[label_hue==0] = 0\n\n# getting the unique colors in the image\nunique_colors = np.unique(labeled_image.reshape(-1, labeled_image.shape[2]), axis=0)\n\nprint \"Colors available in labeled image:\"\nfor x in xrange(unique_colors.shape[0]):\n    print str(x+1)+\"=> B:\"+str(unique_colors[x,0])+\"    G:\"+str(unique_colors[x,1])+\"   R:\"+str(unique_colors[x,2])+\" \"\n\nprint \"\\nSelect one of the colors and give its RGB values \"\n\nr = raw_input(\"B : \")\ng = raw_input(\"G : \")\nb = raw_input(\"R : \")\n\n# making an output image\noutput_image = np.zeros_like(labeled_image)\n\n# getting the object of user input color\nfor x in xrange(labeled_image.shape[0]):\n    for y in xrange(labeled_image.shape[1]):\n        if (labeled_image[x,y,0] == int(r) and labeled_image[x,y,1] == int(g) and labeled_image[x,y,2] == int(b)):\n            output_image[x,y,0:3] = labeled_image[x,y,0:3]\n\n# show the output image\ncv2.imshow(\"Selected\", labeled_image)\ncv2.waitKey(0)\n"
  },
  {
    "path": "Local Histogram Analysis/Slidingwindow.py",
    "content": "import cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nplt.figure(figsize=(12,12))\n\n#reading image as grayscale\nimg = cv2.imread(\"mountains.jpg\",0)\n\ndef slidingWindowEqualization(im, winSize):\n    newImg = np.zeros((im.shape[0], im.shape[1]))\n    for row in xrange(im.shape[0]-winSize+1):\n        for col in xrange(im.shape[1]-winSize+1):\n            newImg[row:row+winSize,col:col+winSize] = cv2.equalizeHist(im[row:row+winSize,col:col+winSize])\n    return newImg\n\nwindowSize = 256\noutput_img = slidingWindowEqualization(img, windowSize)\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Image after transformation\")\nplt.imshow(output_img, cmap=\"gray\")\n\n#writing output image\ncv2.imwrite(\"SlidingWindow.jpg\", output_img)\n\nplt.subplot(212)\nplt.hist(output_img.ravel(),256,[0,256])\nplt.title(\"Histogram\")\n\nplt.show()\n\n"
  },
  {
    "path": "Local Histogram Analysis/tilingGlobal.py",
    "content": "from PIL import Image\nimport matplotlib.pyplot as plt\nimport cv2\nimport numpy as np\n\nimg = cv2.imread('mountains.jpg',0)\nintensity_count = [0] * 256         #Initialize intensity values with 256 zeroes\nL = 255.0\n\nin1 = [0] * 256\nin2 = [0] * 256\nin3 = [0] * 256\nin4 = [0] * 256\n\nheight, width = img.shape[:2]        #Get width and height\nN = height * width * 1.0                 #Get total Pixels\nhalf_height, half_width = height/2, width/2\nhalf_N = (N / 2) * 1.0\n\nim1 = np.zeros((256,256,0))\nim2 = np.zeros((256,256,0))\nim3 = np.zeros((256,256,0))\nim4 = np.zeros((256,256,0))\nhigh_contrast = np.zeros(img.shape)         #Array for global_equalized_new_image\nhigh_contrast_local = np.zeros(img.shape)   #Array for local_equalized_new_image\n\nfor y in range(0, height):\n    for x in range(0, width): \n        intensity_count[img[y,x]] += 1          #Increment each gray_level pixel value according to tile (tile 1, 2, 3 or 4)\n        if y <= height/2 and x < width/2:\n            in1[img[y,x]] += 1\n        elif y <= height/2 and x >= width/2:\n            in2[img[y,x]] += 1\n        elif y > height/2 and x < width/2:\n            in3[img[y,x]] += 1\n        elif y > height/2 and x >= width/2:\n            in4[img[y,x]] += 1\n\nnewList1 = [x / half_N for x in in1]\nnewList2 = [x / half_N for x in in2]\nnewList3 = [x / half_N for x in in3]\nnewList4 = [x / half_N for x in in4]\n\npdf1_array = np.asarray(newList1); cdf1_array = np.cumsum(pdf1_array)\npdf2_array = np.asarray(newList1); cdf2_array = np.cumsum(pdf2_array)\npdf3_array = np.asarray(newList1); cdf3_array = np.cumsum(pdf3_array)\npdf4_array = np.asarray(newList1); cdf4_array = np.cumsum(pdf4_array)\n\napprox1_List = [round(x * L) for x in cdf1_array]\napprox2_List = [round(x * L) for x in cdf2_array]\napprox3_List = [round(x * L) for x in cdf3_array]\napprox4_List = [round(x * L) for x in cdf4_array]\n\nfor y in range(0, height):\n    for x in range(0, width): \n        if y <= height/2 and x < width/2:\n            high_contrast_local[y,x] = approx1_List[img[y,x]]\n        elif y <= height/2 and x >= width/2:\n            high_contrast_local[y,x] = approx2_List[img[y,x]]\n        elif y > height/2 and x < width/2:\n            high_contrast_local[y,x] = approx3_List[img[y,x]]\n        elif y > height/2 and x >= width/2:\n            high_contrast_local[y,x] = approx4_List[img[y,x]]\n\ncv2.imwrite('high_contrast_local.png', high_contrast_local)\n\nnewList = [x / N for x in intensity_count]\n\npdf_array = np.asarray(newList)\ncdf_array = np.cumsum(pdf_array)\n\napprox_List = [round(x * L) for x in cdf_array]\n\nfor y in range(0,height):\n    for x in range(0,width):\n        high_contrast[y,x] = approx_List[img[y,x]] \n\nplt.hist(high_contrast_local.ravel(),256,[0,256])\nplt.xlabel('Intensity Values')\nplt.ylabel('Pixel Count')\nplt.savefig('high_contrast_local.png')\nplt.clf()\n#plt.show()\n\n\ncv2.imwrite('high_contrast_global.png', high_contrast)                         #PLOT THE HISTOGRAMS\nplt.hist(img.ravel(),256,[0,256])\nplt.xlabel('Intensity Values')\nplt.ylabel('Pixel Count')\nplt.savefig('Original.png')\nplt.clf()\n#plt.show()\nplt.hist(high_contrast.ravel(),256,[0,256])\nplt.xlabel('Intensity Values')\nplt.ylabel('Pixel Count')\nplt.savefig('high_contrast_global.png')\nplt.clf()\n#plt.show()\n\n\n"
  },
  {
    "path": "Morphology/segment.py",
    "content": "import cv2\nimport numpy as np\n\nimg = cv2.imread('inp.jpg',0)\n\nret,bin = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)\n\nkernel = np.ones((3,3),np.uint8)\nopened = cv2.morphologyEx(bin, cv2.MORPH_OPEN, kernel)\ncv2.imshow(\"opened\", opened)\n\nkernel = np.ones((5,5),np.uint8)\nclosed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)\nret, output = cv2.threshold(closed,127,255,cv2.THRESH_BINARY_INV)\ncv2.imshow(\"segment\", output)\ncv2.imwrite(\"segment.png\", output)\ncv2.waitKey(0)\n"
  },
  {
    "path": "Morphology/simple.py",
    "content": "import cv2\nimport numpy as np\n\nimg = cv2.imread('signature.png', 0)\nr, img = cv2.threshold(img, 130, 255, cv2.THRESH_BINARY_INV)\ncv2.imshow(\"Original\", img)\ncv2.waitKey(0)\n\nkernel = np.ones((5,5),np.uint8)\n\ndilated = cv2.dilate(img,kernel,iterations = 1)\ncv2.imshow(\"Dilation\", dilated)\ncv2.imwrite(\"dilation.png\", dilated)\ncv2.waitKey(0)\n\neroded = cv2.erode(img,kernel,iterations = 1)\ncv2.imshow(\"Erosion\", eroded)\ncv2.imwrite(\"erosion.png\", eroded)\ncv2.waitKey(0)\n\nopened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)\ncv2.imshow(\"Opening\", opened)\ncv2.imwrite(\"opening.png\", opened)\ncv2.waitKey(0)\n\nclosed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)\ncv2.imshow(\"Closing\", closed)\ncv2.imwrite(\"closing.png\", closed)\ncv2.waitKey(0)\n"
  },
  {
    "path": "README.md",
    "content": "# Basic Digital Image Processing Tasks\n> This repository contains basic implementations of image processing algorithms in python.\n\n## Required Libraries\n*\tPIL\n```shell\n$ pip install pillow\n```\n*\topencv-python\n```shell\n$ pip install opencv-python\n```\n\n## Algorithms\n\n### Gradient\n\n```shell\n$ python gradient.py\n```\n|Original|Gradient|\n|---|---|\n|![Gradient-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Gradient/lena.jpg)|![Gradient-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Gradient/gradient.jpg)|\n\n### Image Negative\n\n```shell\n$ python negative.py binary.jpeg binary\n```\n|Original|Binary Negative|\n|---|---|\n|![Binary-Negative-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Negative/binary.jpg)|![Binary-Negative-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Negative/binary_inverted.png)|\n\n```shell\n$ python negative.py lena.jpg gray\n```\n|Original|Grayscale Negative|\n|---|---|\n|![Gray-Negative-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Negative/grayscale.png)|![Gray-Negative-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Negative/grayscale_inverted.png)|\n\n\n```shell\n$ python negative.py lena.jpg rgb\n```\n|Original|RGB Negative|\n|---|---|\n|![Rgb-Negative-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Negative/rgb.jpg)|![Rgb-Negative-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Negative/rgb_inverted.png)|\n\n### Image Segmentation\n\n```shell\n$ python Segmentation.py\n```\n|Original|Segmented|\n|---|---|\n|![Segmented-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Segmentation/image.png)|![Segmented-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Image%20Segmentation/Capture3.PNG)|\n\n### Centroid\n\n```shell\n$ python Centroid.py\n```\n|Original|Centroid|\n|---|---|\n|![Centroid-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Centroid/Signature.png)|<table><tr><td>Top Left</td><td>Top Right</td></tr><tr><td>![Centroid-TopLeft](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Centroid/TopLeft.png)</td><td>![Centroid-TopRight](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Centroid/TopRight.png)</td></tr><tr><td>Bottom Left</td><td>Bottom Right</td></tr><tr><td>![Centroid-BottomLeft](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Centroid/BottomLeft.png)</td><td>![Centroid-BottomRight](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Centroid/BottomRight.png)</td></tr></table>|\n\n### Connected Component Labelling\n\n```shell\n$ python ccl4.py\n```\n|Original|CCL4 Labelled|\n|---|---|\n|![CCL4-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Connected%20Component%20Labelling/input.png)|![CCL4-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Connected%20Component%20Labelling/ccl.png)|\n\n### Histogram Equalization\n\n```shell\n$ python hist_eq.py\n```\n|Original|Histogram Equalized|\n|---|---|\n|![Hist-eq-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Histogram%20Equalization/hist2.jpg)|![Hist-eq-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Histogram%20Equalization/high_contrast.png)|\n\n### Local Histogram Analysis\n\n|Original|Local Histogram|\n|---|---|\n|![Local-Hist-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Local%20Histogram%20Analysis/mountains.jpg)|![Local-Hist-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Local%20Histogram%20Analysis/high_contrast_local_img.png)|\n\n### Morphology\n\n```shell\n$ python Simple.py\n```\n|Original|Morphology|\n|---|---|\n|![Morphology-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Morphology/signature.png)|<table><tr><td>Erosion</td><td>Dilation</td></tr><tr><td>![Erosion](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Morphology/erosion.png)</td><td>![Dilation](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Morphology/dilation.png)</td></tr><tr><td>Opening</td><td>Closing</td></tr><tr><td>![Opening](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Morphology/opening.png)</td><td>![Closing](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Morphology/closing.png)</td></tr></table>|\n\n### Sharpening\n\n```shell\n$ python sharpen.py\n```\n|Original|Sharpened|\n|---|---|\n|![Sharpened-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Sharpening/inp1.jpg)|![Sharpened-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Sharpening/sharpen.jpg)|\n\n### Skeletonization\n\n```shell\n$ python Skeletonization.py\n```\n![Skeletionization](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Skeletonization/output.png)\n\n### Smoothing\n\n```shell\n$ python AvergingFilter.py\n```\n|Original|Averaging Filter|\n|---|---|\n|![Averaging-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/inp1.jpeg)|![Averaging-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/averaging.jpg)|\n\n```shell\n$ python gaussian.py\n```\n|Original|Gaussian|\n|---|---|\n|![gaussian-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/inp1.jpeg)|![gaussian-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/gaussian.jpg)|\n\n```shell\n$ python unsharp_masking.py\n```\n|Original|Unsharp Masking|\n|---|---|\n|![Unsharp-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/inp2.jpeg)|![Unsharp-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/unsharp_masking.jpg)|\n\n```shell\n$ python median.py\n```\n|Original|Median|\n|---|---|\n|![Unsharp-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/inp3.jpeg)|![Unsharp-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Smoothing/median.jpg)|\n\n\n### XY Cuts\n\n```shell\n$ python XY_Cuts.py\n```\n|Original|XY Cuts|\n|---|---|\n|![XY-Original](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/XY_Cuts/XY-cuts.png)|![XY-Result](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/XY_Cuts/xycut.png)|\n\n### Template Matching\n\n```shell\n$ python TemplateMatching.py\n```\n|Template|Matched in Image|\n|---|---|\n|![Template](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Template%20Matching/template.png)|![MatchedTemplate](https://github.com/mohammaduzair9/Basic-Digital-Image-Processing/blob/master/Template%20Matching/matchedTemplate.png)|\n\n"
  },
  {
    "path": "Sharpening/sharpen.py",
    "content": "import cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\nimport copy\n\nplt.figure(figsize=(12,12))\n#reading image file\nim = cv2.imread(\"inp1.jpg\", 1)\n#function for sharpening filter\ndef sharpenFiltering(img):\n    inputImg = copy.deepcopy(img.astype(np.float))\n    #converting color scale from BGR to GRAY\n    inputImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n    #initialize black image of size equal to given image\n    outputImg = np.zeros(inputImg.shape)\n    #padding the image with zeros\n    inputImg = np.pad(inputImg, (1, 1), 'constant', constant_values=(0))\n    #creating two filters for horizontal and vertical edge detection\n    fh = np.array([[-1.0,-2.0,-1.0],[0.0,0.0,0.0],[1.0,2.0,1.0]])\n    fy = np.array([[-1.0,0.0,1.0],[-2.0,0.0,2.0],[-1.0,0.0,1.0]])\n    #looping through image pixels\n    for row in range(1, inputImg.shape[0]-1):\n        for col in range(1, inputImg.shape[1]-1):\n            dx, dy = 0.0, 0.0\n            #convolving both filters\n            for x_filter in xrange(3):\n                for y_filter in xrange(3):\n                    dx += inputImg[row+x_filter-1][col+y_filter-1]*fh[x_filter][y_filter]\n                    dy += inputImg[row+x_filter-1][col+y_filter-1]*fy[x_filter][y_filter]\n            \n            #magnitude of gradient (instead of just adding dx and dy. we calculate magnitude)\n            pixel = np.sqrt(dx * dx + dy * dy)\n            outputImg[row-1][col-1] = pixel\n    #normalizing pixels\n    outputImg *= 255.0/np.max(outputImg)\n    return outputImg\n\n#applying sharpen filters\noutput = sharpenFiltering(im)\n#writing image to image file\ncv2.imwrite(\"sharpen.jpg\",output)\n#converting color scale from BGR to RGB\nim = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)\n#plotting original image\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Original Image\")\nplt.imshow(im)\n#plotting transformed image\nplt.subplot(212)\nplt.axis('off')\nplt.title(\"Transformed Image\")\nplt.imshow(output, cmap=\"gray\")\n\nplt.show()"
  },
  {
    "path": "Skeletonization/Skeletonization.py",
    "content": "import numpy as np\nimport cv2\n\nimg = cv2.imread('Thumb.png',0)\nret,img = cv2.threshold(img,127,255,cv2.THRESH_BINARY)\n\n# Function for skeletonizing the image\ndef findSkeleton(im):\n    element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))\n    out = np.zeros(im.shape,np.uint8)\n\n    flag = 0 \n    while(not flag):\n        eroded = cv2.erode(im, element)\n        opened = cv2.dilate(eroded, element)\n        opened = cv2.subtract(im,opened)\n        out = cv2.bitwise_or(out,opened)\n        im = eroded.copy()\n        zeros = img.size - cv2.countNonZero(im)\n        flag = 1 if (zeros == img.size) else 0\n    return out\n\noutput = findSkeleton(img)\n\nkernel = np.ones((3,3),np.uint8)\noutput = cv2.dilate(output,kernel)\noutput = cv2.medianBlur(output, 5)\nret,thresh = cv2.threshold(output,127,255,cv2.THRESH_BINARY_INV)\n\nres = np.hstack((img, thresh))\ncv2.imshow(\"output\", cv2.resize(res, dsize=None,fx=0.5, fy=0.5))\ncv2.imwrite(\"task1_output.png\", res)\ncv2.waitKey(0)\n\n"
  },
  {
    "path": "Smoothing/AvergingFilter.py",
    "content": "import cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom Filter import applyFilter\n\nplt.figure(figsize=(12,12))\n\n#reading image from file\nim = cv2.imread(\"inp1.tif\", 0).astype(np.float)\n\nsize = int(raw_input(\"> Enter the size of averaging filter: \"))\n#applying filter on image\noutput = applyFilter(im, filterSize=size)\n\n#writing image to image file\ncv2.imwrite(\"averaging.jpg\",output)\n\n#plotting original image\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Original Image\")\nplt.imshow(im, cmap=\"gray\")\n\n#plotting smoothed image\nplt.subplot(212)\nplt.axis('off')\nplt.title(\"Smoothed Image (avg. filter\"+str(size)+\"x\"+str(size)+\")\")\nplt.imshow(output, cmap=\"gray\")\n\nplt.show()"
  },
  {
    "path": "Smoothing/Filter.py",
    "content": "import numpy as np\nimport copy\n\n#function to apply filter on image\n#call it with just filter size (averaging filter)\n#call it with given filter in imFilter\ndef applyFilter(img, filterSize=None, imFilter=None):\n    filteredImg = copy.deepcopy(img)\n    #if filter is provided\n    if (imFilter is not None):\n        imgFilter = imFilter\n        filterSize = len(imFilter)\n    #if filter is not provided, create an averging filter\n    else:\n        imgFilter = (1.0/(filterSize*filterSize))*np.ones((filterSize,filterSize)) #creating filter\n    \n    paddingSize = filterSize/2\n    #padding the image with zeros\n    filteredImg = np.pad(filteredImg, (paddingSize, paddingSize), 'constant', constant_values=(0))\n    \n    for row in range(paddingSize, filteredImg.shape[0]-paddingSize):\n        for col in range(paddingSize, filteredImg.shape[1]-paddingSize):\n            pixel = 0.0\n            #convolving the filter\n            for x_filter in xrange(filterSize):\n                for y_filter in xrange(filterSize):\n                    pixel += filteredImg[row+x_filter-paddingSize][col+y_filter-paddingSize]*imgFilter[x_filter][y_filter]\n            filteredImg[row,col] = pixel\n    #removing padded pixels\n    filteredImg = filteredImg[paddingSize:filteredImg.shape[0]-paddingSize, paddingSize:filteredImg.shape[1]-paddingSize]\n    return filteredImg"
  },
  {
    "path": "Smoothing/gaussian.py",
    "content": "import cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom Filter import applyFilter\n\nplt.figure(figsize=(12,12))\n\nim = cv2.imread(\"inp1.tif\", 0).astype(np.float)\n\n#creating gaussian filter \ngaussianFilter = np.array([[1,1,2,2,2,1,1],\n                           [1,2,2,4,2,2,1],\n                           [2,2,4,8,4,2,2],\n                           [2,4,8,16,8,4,2],\n                           [2,2,4,8,4,2,2],\n                           [1,2,2,4,2,2,1],\n                           [1,1,2,2,2,1,1]], np.float)\ngaussianFilter /= np.sum(gaussianFilter*1.0)\n\n#applying gaussian filter\noutput = applyFilter(im, imFilter=gaussianFilter)\n#writing image to image file\ncv2.imwrite(\"gaussian.jpg\",output)\n#plotting original image\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Original Image\")\nplt.imshow(im, cmap=\"gray\")\n\n#plotting smoothed image \nplt.subplot(212)\nplt.axis('off')\nplt.title(\"Smoothed Image (gaussian filter7x7 (sigma 1.4))\")\nplt.imshow(output, cmap=\"gray\")\nplt.show()"
  },
  {
    "path": "Smoothing/median.py",
    "content": "import cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\nimport copy\n\nplt.figure(figsize=(12,12))\n#reading image from file\nim = cv2.imread(\"inp3.tif\", 0).astype(np.float)\n#function for median filtering\ndef medianFiltering(img, filterSize):\n    #making deep copy of image\n    filteredImg = copy.deepcopy(img)\n    #calculating padding size\n    paddingSize = filterSize/2\n    #padding the image\n    filteredImg = np.pad(filteredImg, (paddingSize, paddingSize), 'constant', constant_values=(0))\n    #loop through image pixels\n    for row in range(paddingSize, filteredImg.shape[0]-paddingSize):\n        for col in range(paddingSize, filteredImg.shape[1]-paddingSize):\n            kernal = []\n            for x_filter in xrange(filterSize):\n                for y_filter in xrange(filterSize):\n                    kernal.append(filteredImg[row+x_filter-paddingSize][col+y_filter-paddingSize])\n            #calculating median of list\n            filteredImg[row,col] = np.median(kernal)\n    #removing zero padding \n    filteredImg = filteredImg[paddingSize:filteredImg.shape[0]-paddingSize, paddingSize:filteredImg.shape[1]-paddingSize]\n    return filteredImg\n\nsize = int(raw_input(\"> Enter the size of median filter: \"))\n#applying meadian filtering on image\noutput = medianFiltering(im, filterSize=size)\n#writing file to image file\ncv2.imwrite(\"median.jpg\",output)\n#plotting original image\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Original Image\")\nplt.imshow(im, cmap=\"gray\")\n#plotting transformed image\nplt.subplot(212)\nplt.axis('off')\nplt.title(\"Transformed Image\")\nplt.imshow(output, cmap=\"gray\")\n\nplt.show()"
  },
  {
    "path": "Smoothing/unsharp_masking.py",
    "content": "import cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\nimport copy\nfrom Filter import applyFilter\n\nplt.figure(figsize=(12,12))\n#reading image from file\nim = cv2.imread(\"inp2.tif\", 0).astype(np.float)\n\n#function for unsharp masking\ndef unsharpMasking(img):\n    inputImg = copy.deepcopy(img)\n    blurredImg = applyFilter(inputImg, filterSize=5)\n    mask = inputImg - blurredImg\n    result = inputImg + mask\n    return result\n#unsharp masking the image\noutput = unsharpMasking(im)\n#writing image to image file\ncv2.imwrite(\"unsharp_masking.jpg\",output)\n#plotting original image\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Original Image\")\nplt.imshow(im, cmap=\"gray\")\n#plotting transformed image\nplt.subplot(212)\nplt.axis('off')\nplt.title(\"Transformed Image\")\nplt.imshow(output, cmap=\"gray\")\n\nplt.show()"
  },
  {
    "path": "Smoothing/weightedavg.py",
    "content": "import cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom Filter import applyFilter\n\nplt.figure(figsize=(12,12))\n\n#reading image from file\nim = cv2.imread(\"inp1.tif\", 0).astype(np.float)\n\n#creating weighted filter:\n#[1 2 1],\n#[2 4 2],\n#[1 2 1]\nweightedFilter = (1.0/16)*np.array([[1,2,1],[2,4,2],[1,2,1]], np.int32)\n\n#applying filter on image\noutput = applyFilter(im, imFilter=weightedFilter)\n\n#writing image to image file\ncv2.imwrite(\"weightedavg.jpg\",output)\n\n#plotting original image\nplt.subplot(211)\nplt.axis('off')\nplt.title(\"Original Image\")\nplt.imshow(im, cmap=\"gray\")\n\n#plotting smoothed image\nplt.subplot(212)\nplt.axis('off')\nplt.title(\"Smoothed Image (weighted avg. filter3x3)\")\nplt.imshow(output, cmap=\"gray\")\nplt.show()"
  },
  {
    "path": "Template Matching/TemplateMatching.py",
    "content": "import cv2\nimport numpy as np\n\nimage = cv2.imread('image.png')\ntemplate = cv2.imread('template.png')\n(templateHeight, templateWidth) = template.shape[:2]\n\nmatchResult = cv2.matchTemplate(image, template, cv2.TM_CCOEFF)\n(_, _, minLoc, maxLoc) = cv2.minMaxLoc(matchResult)\n\ntopLeft = maxLoc\nbotRight = (topLeft[0] + templateWidth, topLeft[1] + templateHeight)\nroi = image[topLeft[1]:botRight[1], topLeft[0]:botRight[0]]\n \nmask = np.zeros(image.shape, dtype = \"uint8\")\nimage = cv2.addWeighted(image, 0.25, mask, 0.75, 0)\n\nimage[topLeft[1]:botRight[1], topLeft[0]:botRight[0]] = roi\n \ncv2.imwrite(\"matchedTemplate.png\", image)\n"
  },
  {
    "path": "XY_Cuts/XY_Cuts.py",
    "content": "import cv2\nfrom matplotlib import pyplot as plt\n\ndef xycut(image, image_path):\n    # reading image\n    img = plt.imread(image_path)\n    fig, ax = plt.subplots()\n    ax.imshow(img)\n\n    black_pix = []\n    white_lines = []\n    # detecting the white lines\n    for i in range(0, bin_img.shape[0]):\n        # if number of white phixels in row is greater than 750\n        if (bin_img[i].sum() / 255 > 750):\n\n            # draw horizontal lines\n            ax.axhline(y=i, color='green')\n        else:\n            # black pixels on x-axis\n            for j in range(0, bin_img.shape[1]):\n                if (bin_img[i][j] == 0):\n                    black_pix.append(j)\n\n    if len(black_pix) != 0:\n        # draw first & last vertical line only\n        ax.axvline(x=min(black_pix), linewidth=3, color='green')\n        ax.axvline(x=max(black_pix), linewidth=3, color='green')\n\n    # remove the axis\n    ax.set_axis_off()\n    # saving new figure\n    plt.savefig('xycut.png', bbox_inches='tight')\n    # show the figure\n    plt.show()\n\n\n# load image as greyscale\nimage = cv2.imread(\"XY-cuts.png\", 0)\n# binarize image\n(_, bin_img) = cv2.threshold(image, 120, 255, cv2.THRESH_BINARY)\n# call xycut function\nxycut(bin_img, \"XY-cuts.png\")\n"
  }
]