''' pathToDir = "../../Images/Chapter2/Input/" imageName = "Giraffe.png" # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Create coefficients Image. Maximum frequency according to sampling maxFreqW = int(width / 2) maxFreqH = int(height / 2) numCoeffW = 1 + 2 * maxFreqW numCoeffH = 1 + 2 * maxFreqH coeff = createImageF(numCoeffW, numCoeffH) # Adjust the size of the data to be even m = float(width) n = float(height) if width % 2 == 0: m = width + 1.0 if height % 2 == 0: n = height + 1.0 # Fundamental frequency ww = (2.0 * pi) / m wh = (2.0 * pi) / n # Compute values for u in range(-maxFreqW, maxFreqW + 1):
imageName = Input image name ''' pathToDir = "../../Images/Chapter2/Input/" imageName = "Giraffe.png" # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show images showImageL(inputImage) # Compute coefficients coeff, maxFreqW, maxFreqH = computeCoefficients(inputImage) # Create low and high versions coeffLow = createImageF(1 + 2 * maxFreqW, 1 + 2 * maxFreqH, 2) coeffHigh = createImageF(1 + 2 * maxFreqW, 1 + 2 * maxFreqH, 2) # Filter cutFrequency = maxFreqW / 8 for kw,kh in itertools.product(range(-maxFreqW, maxFreqW + 1), \ range(-maxFreqH, maxFreqH + 1)): IndexW, indexH = kw + maxFreqW, kh + maxFreqH if sqrt(kw * kw + kh * kh) < cutFrequency: coeffLow[indexH, IndexW][0] = coeff[indexH, IndexW][0] coeffLow[indexH, IndexW][1] = coeff[indexH, IndexW][1] else: coeffHigh[indexH, IndexW][0] = coeff[indexH, IndexW][0] coeffHigh[indexH, IndexW][1] = coeff[indexH, IndexW][1]
maxDisp = 10 step = 10 # Read image into array. both images must have same size inputImage1, width, height = imageReadL(pathToDir + image1Name) inputImage2, _, _ = imageReadL(pathToDir + image2Name) # Show input image showImageL(inputImage1) showImageL(inputImage2) # The center of the kernel kernelCentre = int((kernelSize - 1) / 2) # Compute Motion in sampled points motionMagnitude = createImageF(width, height) motionDirection = createImageF(width, height) motionWeight = createImageF(width, height) for x,y in itertools.product(range(2 * step, width-2*step, step), \ range(2 * step, height-2*step,step)): minDiference, nextDiference = float("inf"), float("inf") mDisp = [0,0] for dx,dy in itertools.product(range(-maxDisp, maxDisp), \ range(-maxDisp, maxDisp)): if dx != 0 or dy != 0: differenceMatching = 0 for wx,wy in itertools.product(range(0, kernelSize), \ range(0, kernelSize)): y1, x1 = y + wy - kernelCentre, x + wx - kernelCentre y2, x2 = y1 + dy, x1 + dx
pathToDir = "../../Images/Chapter7/Input/" imageName = "f14rs.png" numMoments = 4 background = [200, 255] # white background image # Read image into array and show inputImage, width, height = imageReadL(pathToDir+imageName) showImageL(inputImage) # Get a list that contains the pixels of the shape in the form (y,x,val) # We could have used the border pixels imageRegion = pixlesList(inputImage, background) # Compute geometric moments numPoints = len(imageRegion) M = createImageF(numMoments,numMoments) for m,n in itertools.product(range(0, numMoments), range(0, numMoments)): for indexPixel in range(0, numPoints): y = (imageRegion[indexPixel])[0] x = (imageRegion[indexPixel])[1] v = (imageRegion[indexPixel])[2] M[n,m] += (x**n) * (y**m) * v # Geometric central Moments xc,yc = M[1,0]/M[0,0], M[0,1]/M[0,0] centMom = createImageF(numMoments,numMoments) for m,n in itertools.product(range(0, numMoments), range(0, numMoments)): for indexPixel in range(0, numPoints): y = (imageRegion[indexPixel])[0] x = (imageRegion[indexPixel])[1] v = (imageRegion[indexPixel])[2]
inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Apply Gaussian kernel gaussianKernel = createGaussianKernel(GaussianKernelSize) gaussianImage = applyKernelF(inputImage, gaussianKernel) # Apply Sobel kernel. We use normalized magnitude in this example sobelX, sobelY = createSobelKernel(sobelKernelSize) magnitude, angle, _, _ = applyKernelMA(gaussianImage, sobelX, sobelY, normalizeMagnitude) # To store maximum suppression image maxImage = createImageF(width, height) # Non-maximum suppression border = GaussianKernelSize for x,y in itertools.product(range(border, width-border), \ range(border, height-border)): # Only potential edges can be maximum if magnitude[y, x] > lowerT: # The normal angle is perpendicular to the edge angle normalAngle = angle[y, x] - pi / 2.0 # Make sure the angle is between 0 and pi while normalAngle < 0: normalAngle += pi while normalAngle > pi:
lowerT = 0.3 peakDetection = 0.7 # Read image into array and show inputImage, width, height = imageReadL(pathToDir + imageName) showImageL(inputImage) # Compute edges magnitude, angle = applyCannyEdgeDetector(inputImage, gaussianKernelSize, sobelKernelSize, upperT, lowerT) showImageF(magnitude) # Line parametrisation for normals from 0 to 360 degrees and r positive form the image centre # Parametrisation r = (x-cx) * cos(t) + (y-cy) * sin(t) maxLenght = int(sqrt(height * height + width * width) / 2) accumulator = createImageF(maxLenght, 360) cx = int(width / 2) cy = int(height / 2) # Gather evidence for x, y in itertools.product(range(0, width), range(0, height)): if magnitude[y, x] != 0: for m in range(0, 360): angle = (m * pi) / 180.0 r = (x - cx) * cos(angle) + (y - cy) * sin(angle) bucket = int(r) if bucket > 0 and bucket < maxLenght - 1: weight = r - int(r) accumulator[m, bucket] += (1.0 - weight) accumulator[m, bucket + 1] += weight
scale = max(max(inputWidth, inputHeight) / float(reducedSize), 1.0) width, height = int(inputWidth / scale), int(inputHeight / scale) scaledImage = scaleImageL(inputImage, width, height) showImageL(scaledImage) # Get a list that contains the pixels of the shape in the form (y,x,v) shapeImage = pixlesList(scaledImage, background) numPoints = len(shapeImage) # Polynomials, coefficients and weights for the Krawtchouk polynomials # Considering that A*C = k. For a the coefficients and C the powers x, x^2, x^3,.. N = max(width, height) kW, aW, sigma, ro, w = weightedKrawtchoukPolynomials(p, N) # Krawtchouk moments of the shape by standard definition Q = createImageF(numMoments, numMoments) for m, n in itertools.product(range(0, numMoments), range(0, numMoments)): for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] v = (shapeImage[indexPixel])[2] Q[n, m] += w[x, m] * kW[x, m] * w[y, n] * kW[y, n] * v printImageRangeF(Q, [0, numMoments - 1], [0, numMoments - 1], " 8.2f") # Krawtchouk moments from the geometric moments Gij = x**i , y**j. G = createImageF(N, N) for i, j in itertools.product(range(0, N), range(0, N)): for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] v = (shapeImage[indexPixel])[2] G[j, i] += sqrt(sigma[x] * sigma[y]) * y**j * x**i * v
kernelSize = Kernel size sigma = Standard deviation ''' pathToDir = "../../Images/Chapter3/Input/" imageName = "Giraffe.png" kernelSize = 9 sigma = 3.0 # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Create image to store kernel kernelImage = createImageF(kernelSize, kernelSize) # Three float array to store colors to be used in the surface plot colorsRGB = createImageF(kernelSize, kernelSize, 3) # Set the pixels of Gaussian kernel centre = (kernelSize - 1) / 2 sumValues = 0 for x,y in itertools.product(range(0, kernelSize), range(0, kernelSize)): kernelImage[y,x] = exp( -0.5 * (pow((x - centre)/sigma, 2.0) + \ pow((y - centre)/sigma, 2.0)) ) sumValues += kernelImage[y,x] # This is only set for the plot colorsRGB[y,x] = [kernelImage[y,x], kernelImage[y,x], kernelImage[y,x]]
def findLongestSegment(edges): height, width = len(edges), len(edges[0]) # Find line segments segmentsList = [] segmentsImage = createImageF(width, height) maxSegmentLenght = 0 maxSegmentIndex = 0 for x, y in itertools.product(range(0, width), range(0, height)): if edges[y, x] != 0 and segmentsImage[y, x] == 0: segment = [] segmentPoints = [(y, x)] segmentsImage[y, x] = 255 while len(segmentPoints) > 0: yc = (segmentPoints[0])[0] xc = (segmentPoints[0])[1] segment.append((yc, xc)) segmentPoints = segmentPoints[1:] for dx, dy in itertools.product(range(-1, 2), range(-1, 2)): xn, yn = xc + dx, yc + dy if dx != 0 or dy != 0 and xn > 0 and yn > 0 and xn < width and yn < height: if edges[yn, xn] != 0 and segmentsImage[yn, xn] == 0: segmentPoints.append((yn, xn)) segmentsImage[yn, xn] = 255 segmentsList.append(segment) if len(segment) > maxSegmentLenght: maxSegmentLenght = len(segment) maxSegmentIndex = len(segmentsList) - 1 mainSegment = [] segment = segmentsList[maxSegmentIndex] curentElement = segment.pop(0) sy, sx = curentElement[0], curentElement[1] mainSegment.append(curentElement) numPoints = len(segment) while numPoints > 0: closestElement = [0, float("inf")] cy, cx = curentElement[0], curentElement[1] for p in range(0, numPoints): y, x = (segment[p])[0], (segment[p])[1] d = sqrt((cx - x) * (cx - x) + (cy - y) * (cy - y)) if d < closestElement[1] or (d == closestElement[1] and y > cy): closestElement = [p, d] # If we are closer to the first point, then end now dFirst = sqrt((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy)) if (cx != sx or cy != sy) and 2 * dFirst < closestElement[1]: break curentElement = segment.pop(closestElement[0]) numPoints = len(segment) mainSegment.append(curentElement) numPoints = len(mainSegment) # Average to get more accurate direction averageSize = 1 totalPixels = float(1 + 2 * averageSize) mainSegmentAverage = [] for p in range(0, numPoints): y, x = 0, 0 for w in range(-averageSize, averageSize + 1): p1 = p + w if p1 < 0: p1 = p1 + numPoints if p1 >= numPoints: p1 = p1 - numPoints x += (mainSegment[p1])[1] y += (mainSegment[p1])[0] mainSegmentAverage.append((y / totalPixels, x / totalPixels)) return mainSegmentAverage
m = atan(-float(y1 - refPoint[0]) / (x1 - refPoint[1])) else: m = 1.57 k = angleTemplate[y1, x1] - m # Scale distCentre = sqrt((y1 - refPoint[0]) * (y1 - refPoint[0]) + (x1 - refPoint[1]) * (x1 - refPoint[1])) distPoints = sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1)) c = distCentre / distPoints # Insert in the table. The angle is in the interval -pi/2 to pi/2 entryIndex = int((beta + (pi / 2.0)) / deltaAngle) entry = rTable[entryIndex] entry.append((k, c)) # Gather evidence for the location accumulator = createImageF(width, height) for x1, y1 in itertools.product(range(0, width), range(0, height)): if magnitude[y1, x1] != 0: # Looking for potential the second points along a line secondPoints = [] m = tan(angle[y1, x1] - alpha) if m > -1 and m < 1: for delta in range(minimaDistPoints, maxDistPoints): x2 = min(x1 + delta, width - 1) y2 = int(y1 - m * (x2 - x1)) if y2 > 0 and y2 < height and magnitude[y2, x2] != 0: secondPoints.append((y2, x2)) break for delta in range(minimaDistPoints, maxDistPoints): x2 = max(0, x1 - delta) y2 = int(y1 - m * (x2 - x1))
def watherShed(distanceImage, shapeImage, suppWindow): height, width = len(distanceImage), len(distanceImage[0]) watershedImage = createImageF(width, height) # Initial regions by finding the maximum regionIndex = 1 # Start id for a region. Any number different from zero numPoints = len(shapeImage) for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] if watershedImage[y, x] == 0: peak = True for wx,wy in itertools.product(range(x-suppWindow, x+suppWindow+1), \ range(y-suppWindow, y+suppWindow+1)): if wy >= 0 and wy < height and wx >= 0 and wx < width: if watershedImage[wy, wx] != 0 or \ distanceImage[y, x] < distanceImage[wy, wx]: peak = False if peak: for wx,wy in itertools.product(range(x-suppWindow, x+suppWindow+1), \ range(y-suppWindow, y+suppWindow+1)): if wy >= 0 and wy < height and wx >= 0 and wx < width: watershedImage[wy, wx] = regionIndex regionIndex += 1 floodRegion = [] # The region we need to flood for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] if watershedImage[y, x] == 0: floodRegion.append((y, x)) # This is not required. We do it to get a better display # Create random regions ID. We change the ID for a random value so we get a random gray level when showing the regions c = sample(range(regionIndex), regionIndex) for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] if watershedImage[y, x] != 0: watershedImage[y, x] = c[int(watershedImage[y, x])] + 1 # Flooding maxDistance, _ = imageMaxMin(distanceImage) for floodValue in range(int(maxDistance), 0, -1): flooded = True while flooded: flooded = False newFloodRegion = [] growRegion = [] shuffle(floodRegion) for indexPixel in range(0, len(floodRegion)): y, x = (floodRegion[indexPixel])[0], ( floodRegion[indexPixel])[1] # Points not flooded will be considered in following iterations if distanceImage[y, x] <= floodValue: newFloodRegion.append((y, x)) else: # list of neighbours n = [] for wx, wy in itertools.product(range(-1, 2), range(-1, 2)): posX, posY = x + wx, y + wy if posY > -1 and posY < height and posX > -1 and posX < width: if watershedImage[posY, posX] != 0: n.append(watershedImage[posY, posX]) # No neighbours, so we cannot grow if (len(n) == 0): newFloodRegion.append((y, x)) else: # Grow of only one type of region if len(set(n)) == 1: growRegion.append((y, x, n[0])) flooded = True for pixel in growRegion: watershedImage[pixel[0], pixel[1]] = pixel[2] floodRegion = newFloodRegion # Set the borders shedID = regionIndex + 1 for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] if watershedImage[y, x] == 0 and distanceImage[y, x] > 0.5: watershedImage[y, x] = shedID return watershedImage
pathToDir = "../../Images/Chapter2/Input/" imageName = "Square.png" # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Create coefficients Image. Two floats to represent a complex number # Maximum frequency according to sampling maxFreqW = int(width / 2) maxFreqH = int(height / 2) numCoeffW = 1 + 2 * maxFreqW numCoeffH = 1 + 2 * maxFreqH coeff = createImageF(numCoeffW, numCoeffH, 2) # Adjust the size of the data to be even m = float(width) n = float(height) if width % 2 == 0: m = width + 1.0 if height % 2 == 0: n = height + 1.0 # Fundamental frequency ww = (2.0 * pi) / m wh = (2.0 * pi) / n # Fourier Transform for u in range(-maxFreqW, maxFreqW + 1):
from ImagePropertiesUtilities import imageMaxMin from PlotUtilities import plotSurface # Math and iteration from math import exp from timeit import itertools ''' Parameters: kernelSize = Size of the kernel sigma = Standard deviation of the kernel ''' kernelSize = 15 sigma = 1.5 # To store kernel kernelLaplacian = createImageF(kernelSize, kernelSize) # Create kernel s2Inv = 1.0 / (sigma * sigma) kernelCentre = (kernelSize - 1) / 2 # Generate kernel values sumValues = 0.0 for x, y in itertools.product(range(0, kernelSize), range(0, kernelSize)): nx2 = float(x - kernelCentre) * float(x - kernelCentre) ny2 = float(y - kernelCentre) * float(y - kernelCentre) s = 0.5 * (nx2 + ny2) * s2Inv kernelLaplacian[y, x] = -s2Inv * s2Inv * (1.0 - s) * exp(-s) sumValues += kernelLaplacian[y, x]
''' pathToDir = "../../Images/Chapter2/Input/" imageName = "Square.png" # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Create coefficients Image. Two floats to represent a complex number maxFrequencyW = int(width / 2) maxFrequencyH = int(height / 2) numCoefficientsW = 1 + 2 * maxFrequencyW numCoefficientsH = 1 + 2 * maxFrequencyH coefficients = createImageF(numCoefficientsW, numCoefficientsH, 2) # Adjust the size of the data to be even m = float(width) n = float(height) if width % 2 == 0: m = width + 1.0 if height % 2 == 0: n = height + 1.0 # Fundamental frequency ww = (2.0 * pi) / m wh = (2.0 * pi) / n # Compute coefficients for kw in range(-maxFrequencyW, maxFrequencyW + 1):
from timeit import itertools ''' Parameters: pathToDir = Input image directory imageName = Input image name ''' pathToDir = "../../Images/Chapter4/Input/" imageName = "Squares.png" # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) outputMagnitude = createImageF(width, height) outputDirection = createImageF(width, height) for x, y in itertools.product(range(0, width - 1), range(0, height - 1)): mX, mY = 0.0, 0.0 for c in range(-1, 2): mX += float(inputImage[y - 1, x + c]) - float(inputImage[y + 1, x + c]) mY += float(inputImage[y + c, x - 1]) - float(inputImage[y + c, x + 1]) outputMagnitude[y, x] = sqrt(mX * mX + mY * mY) outputDirection[y, x] = atan2(mY, mX) # Show output image showImageF(outputMagnitude) showImageF(outputDirection) # Print pixel's values in an image range
pathToDir = "../../Images/Chapter5/Input/" imageName = "Eye.png" templateName = "EyeTemplate.png" addQuadraticTerm = True # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) templateImage, widthTemplate, heightTemplate = imageReadL(pathToDir + templateName) # We pad the input and template to this size widthPad = width + widthTemplate - 1 heightPad = height + heightTemplate - 1 # Pad input inputPad = createImageF(widthPad, heightPad) for x, y in itertools.product(range(0, width), range(0, height)): inputPad[y, x] = inputImage[y, x] # Pad and invert template templatePad = createImageF(widthPad, heightPad) templatePadFlip = createImageF(widthPad, heightPad) for x, y in itertools.product(range(0, widthTemplate), range(0, heightTemplate)): templatePad[y, x] = templateImage[y, x] templatePadFlip[y, x] = templateImage[heightTemplate - y - 1, widthTemplate - x - 1] # Show input image and template showImageF(inputPad) showImageF(templatePad)
''' Parameters: pathToDir = Input image directory imageName = Input image name ''' pathToDir = "../../Images/Chapter4/Input/" imageName = "Squares.png" # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Create images to store the results horizEdges = createImageF(width, height) vertEdges = createImageF(width, height) outputEdges = createImageF(width, height) for x, y in itertools.product(range(0, width - 1), range(0, height - 1)): horizEdges[y, x] = abs(float(inputImage[y, x]) - float(inputImage[y + 1, x])) vertEdges[y, x] = abs(float(inputImage[y, x]) - float(inputImage[y, x + 1])) outputEdges[y,x] = abs(2.0* float(inputImage[y,x]) - \ float(inputImage[y+1,x]) - float(inputImage[y,x+1])) # Show horizontal, vertical and all edges showImageF(horizEdges)
# Obtain the angular functions and plot sumArcLenghts, normArcLenghts, angularFunc, cumulativeFunc, cumulativeNormFunc = \ computeAngularFunctions(shape) plotCurveXY(sumArcLenghts,angularFunc, [-3.2, 3.2]) plotCurveXY(normArcLenghts,cumulativeNormFunc, [-3.2, 3.2]) # Number of coefficients numEdges = len(sumArcLenghts) shapeLenght = sumArcLenghts[numEdges - 1] # If number descriptors is 0 use the maximum according to the lenght if numDescriptors == 0: numDescriptors = 1 + int(numEdges /2) # Compute coefficients coefficients = createImageF(numDescriptors, 2) lenghtNorm = 2.0 * pi / shapeLenght for k in range(1, numDescriptors): arcLenght = 0 for p in range(0, numEdges): coefficients[0, k] += cumulativeFunc[p] * (sumArcLenghts[p] - arcLenght) \ * cos(k * sumArcLenghts[p] * lenghtNorm) coefficients[1, k] += cumulativeFunc[p] * (sumArcLenghts[p] - arcLenght) \ * sin(k * sumArcLenghts[p] * lenghtNorm) arcLenght = sumArcLenghts[p] coefficients[0, k] = coefficients[0, k] *(2.0/shapeLenght) coefficients[1, k] = coefficients[1, k] *(2.0/shapeLenght) - (2.0/k) # Rotation invariant descriptors descriptors = createVectorF(numDescriptors)
imageName = "Logs.png" suppWindow = 5 # Read image into array and show inputImage, width, height = imageReadL(pathToDir + imageName) showImageL(inputImage) # Apply Sobel kernel. We use normalized magnitude in this example sobelX, sobelY = createSobelKernel(3) normalizeMagnitude = False magnitude, _, _, _ = applyKernelMA(inputImage, sobelX, sobelY, normalizeMagnitude) showImageF(magnitude) # Apply Gaussian kernel gaussianKernel = createGaussianKernel(10) gaussianImage = applyKernelF(magnitude, gaussianKernel) # Invert the image and add all pixels to the shape shapeImage = [] distanceImage = createImageF(width, height) maxGradient, minGradient = imageMaxMin(gaussianImage) for x, y in itertools.product(range(0, width), range(0, height)): distanceImage[y, x] = maxGradient - gaussianImage[y, x] shapeImage.append((y, x)) showImageF(distanceImage) # Watershed of the distance image watershed = watherShed(distanceImage, shapeImage, suppWindow) showImageF(watershed)