def applyKernelMA(inputImage, kernelX, kernelY, normalizeMagnitude=False):
    height = len(inputImage)
    width = len(inputImage[0])

    kernelHeight = len(kernelX)
    kerelWidth = len(kernelX[0])

    kernelCentreY = int((kernelHeight - 1) / 2)
    kernelCentreX = int((kerelWidth - 1) / 2)

    # Create images to store the result
    magnitude = createImageF(width, height)
    direction = createImageF(width, height)
    imageX = createImageF(width, height)
    imageY = createImageF(width, height)

    # Convolution with two kernels
    for x,y in itertools.product(range(kernelCentreX, width - kernelCentreX),          \
                                 range(kernelCentreY, height - kernelCentreY)):
        sumKernel = [0.0, 0.0]
        sumKernelWeights = [0.0, 0.0]
        for wx, wy in itertools.product(range(0, kerelWidth),
                                        range(0, kernelHeight)):

            posY = y + wy - kernelCentreY
            posX = x + wx - kernelCentreX

            if posY > -1 and posY < height and posX > -1 and posX < width:
                sumKernel[0] += float(inputImage[posY, posX]) * float(
                    kernelX[wy, wx])
                sumKernelWeights[0] += float(kernelX[wy, wx])

                sumKernel[1] += float(inputImage[posY, posX]) * float(
                    kernelY[wy, wx])
                sumKernelWeights[1] += float(kernelY[wy, wx])

        # If we have to normalize
        if sumKernelWeights[0] != 0.0:
            imageX[y, x] = sumKernel[0] / sumKernelWeights[0]
        else:
            imageX[y, x] = sumKernel[0]

        # If we have to normalize
        if sumKernelWeights[1] != 0.0:
            imageY[y, x] = sumKernel[1] / sumKernelWeights[1]
        else:
            imageY[y, x] = sumKernel[1]

        magnitude[y, x] = sqrt(imageX[y, x] * imageX[y, x] +
                               imageY[y, x] * imageY[y, x])
        direction[y, x] = atan2(imageY[y, x], imageX[y, x])

    if normalizeMagnitude == True:
        maximum, minimum = imageMaxMin(magnitude)

        for x, y in itertools.product(range(0, width), range(0, height)):
            magnitude[y, x] = (magnitude[y, x] - minimum) / float(maximum -
                                                                  minimum)

    return magnitude, direction, imageX, imageY
Example #2
0
def regionSize(backProjImage, newBackProjImage, pos, newPos, sizeReg):
    # Compute geometric moments
    momS = createImageF(3, 3)
    momT = createImageF(3, 3)
    sizeSearch = [int(sizeReg[0] * 1.5), int(sizeReg[1] * 1.5)]
    for deltaX, deltaY in itertools.product(range(-sizeSearch[0], sizeSearch[0]),   \
                                            range(-sizeSearch[1], sizeSearch[1])):
        x, y = pos[0] + deltaX, pos[1] + deltaY
        for m, n in itertools.product(range(0, 3), range(0, 3)):
            momS[n, m] += (x**n) * (y**m) * backProjImage[y, x]

        x, y = newPos[0] + deltaX, newPos[1] + deltaY
        for m, n in itertools.product(range(0, 3), range(0, 3)):
            momT[n, m] += (x**n) * (y**m) * newBackProjImage[y, x]

    xc, yc = momS[1, 0] / momS[0, 0], momS[0, 1] / momS[0, 0]
    a = momS[2, 0] / momS[0, 0] - xc * xc
    b = 2 * (momS[1, 1] / momS[0, 0] - xc * yc)
    c = momS[0, 2] / momS[0, 0] - yc * yc
    sxS = int(sqrt((a + c - sqrt(b * b + (a - c) * (a - c)) / 2)))
    syS = int(sqrt((a + c + sqrt(b * b + (a - c) * (a - c)) / 2)))

    xc, yc = momT[1, 0] / momT[0, 0], momT[0, 1] / momT[0, 0]
    a = momT[2, 0] / momT[0, 0] - xc * xc
    b = 2 * (momT[1, 1] / momT[0, 0] - xc * yc)
    c = momT[0, 2] / momT[0, 0] - yc * yc
    sx = int(sqrt((a + c - sqrt(b * b + (a - c) * (a - c)) / 2)))
    sy = int(sqrt((a + c + sqrt(b * b + (a - c) * (a - c)) / 2)))

    sy = sy * sizeReg[1] / syS
    sx = sx * sizeReg[0] / sxS

    return [int(xc), int(yc)], [int(sx), int(sy)]
Example #3
0
def weightedKrawtchoukPolynomials(p, width):

    # Data containers
    sigma = createVectorF(width)
    ro = createVectorF(width)
    K = createImageF(width, width)

    # Coefficient size
    N = width - 1

    # Weight
    for x in range(0, width):
        sigma[x] = nCr(N, x) * pow(p, x) * pow(1 - p, N - x)

    # Scale factor. Commented direct computation and using for to avoid factorial
    #for n in range(0,width):
    #    ro[n] = pow(-1,n) * pow((1-p)/p,n) * (float(factorial(n)) / risingFactorial(-N, n))
    ro[0] = 1
    for n in range(1, N):
        ro[n] = (-1 * ((1.0 - p) / p) * n / (-N + (n - 1))) * ro[n - 1]
    ro[N] = (((1.0 - p) / p) * N) * ro[N - 1]

    # Krawtchouk matrix that store result of the polynomial
    # Each row is a polynomial each column is the polynomial value for an x value
    # Alternatively, we could have used the polynomial generating function
    q = 1.0 / p
    for n, x in itertools.product(range(0, width), range(0, width)):
        for s in range(0, width):
            K[n, x] += pow(-1, s) * nCr(N - x, n - s) * nCr(x, s) * pow(
                q - 1, n - s)

    # Normalize rows for stability
    for n in range(0, width):
        scale = K[n, 0]
        for x in range(0, width):
            K[n, x] /= scale

    # Obtain the coefficients A of the polynomials from K
    # Solve for the coefficients A in A*C = K
    C = createImageF(width, width)
    for n, x in itertools.product(range(0, width), range(0, width)):
        C[n, x] = pow(x, n)

    CT = np.transpose(C)
    KT = np.transpose(K)
    AT = np.linalg.solve(CT,
                         KT)  # solves the equation A*x=b   A*C = k, C'*A' = K'
    A = np.transpose(AT)

    # Product defining the weighted
    w = createImageF(width, width)
    for n, x in itertools.product(range(0, width), range(0, width)):
        w[n, x] = sqrt(sigma[x] / ro[n])

    return K, A, sigma, ro, w
Example #4
0
def backProjection(sourceImage, targetImage, qSource, pSource, pTarget,
                   sizeReg, histoSize):
    height, width = len(sourceImage), len(sourceImage[0])

    colourScale = 256.0 / histoSize

    # Projection
    projectionSource = createImageF(width, height)
    projectionTarget = createImageF(width, height)
    for x, y in itertools.product(range(0, width), range(0, height)):

        Cb, Cr = colourFeature(sourceImage[y, x], colourScale)
        projectionSource[y, x] = qSource[Cr, Cb]

        Cb, Cr = colourFeature(targetImage[y, x], colourScale)
        projectionTarget[y, x] = qSource[Cr, Cb]

    # Compute geometric moments
    momS = createImageF(3, 3)
    momT = createImageF(3, 3)
    sizeSearch = [int(sizeReg[0] * 1.5), int(sizeReg[1] * 1.5)]
    for deltaX, deltaY in itertools.product(range(-sizeSearch[0], sizeSearch[0]),   \
                                            range(-sizeSearch[1], sizeSearch[1])):
        x, y = pSource[0] + deltaX, pSource[1] + deltaY
        for m, n in itertools.product(range(0, 3), range(0, 3)):
            momS[n, m] += (x**n) * (y**m) * projectionSource[y, x]

        x, y = pTarget[0] + deltaX, pTarget[1] + deltaY
        for m, n in itertools.product(range(0, 3), range(0, 3)):
            momT[n, m] += (x**n) * (y**m) * projectionTarget[y, x]

    xc, yc = momS[1, 0] / momS[0, 0], momS[0, 1] / momS[0, 0]
    a = momS[2, 0] / momS[0, 0] - xc * xc
    b = 2 * (momS[1, 1] / momS[0, 0] - xc * yc)
    c = momS[0, 2] / momS[0, 0] - yc * yc
    sxS = int(sqrt((a + c - sqrt(b * b + (a - c) * (a - c)) / 2)))
    syS = int(sqrt((a + c + sqrt(b * b + (a - c) * (a - c)) / 2)))

    xc, yc = momT[1, 0] / momT[0, 0], momT[0, 1] / momT[0, 0]
    a = momT[2, 0] / momT[0, 0] - xc * xc
    b = 2 * (momT[1, 1] / momT[0, 0] - xc * yc)
    c = momT[0, 2] / momT[0, 0] - yc * yc
    sx = int(sqrt((a + c - sqrt(b * b + (a - c) * (a - c)) / 2)))
    sy = int(sqrt((a + c + sqrt(b * b + (a - c) * (a - c)) / 2)))

    sy = sy * sizeReg[1] / syS
    sx = sx * sizeReg[0] / sxS

    return [int(xc), int(yc)], [int(sx), int(sy)]
Example #5
0
def findLongestCentredSegmentinImage(imageName, gaussianKernelSize,
                                     sobelKernelSize, upperT, lowerT):
    # Read image into array and show
    inputImage, width, height = imageReadL(imageName)

    # Compute edges and find the segment in the image
    magnitude, _ = applyCannyEdgeDetector(inputImage, gaussianKernelSize,
                                          sobelKernelSize, upperT, lowerT)
    mainSegmentAverage = findLongestSegment(magnitude)

    # Compute centre
    numPoints = len(mainSegmentAverage)
    centre = [0, 0]
    for p in range(0, numPoints):
        centre[0] += (mainSegmentAverage[p])[0]
        centre[1] += (mainSegmentAverage[p])[1]
    centre[0] /= numPoints
    centre[1] /= numPoints

    # Respect to the center and convert to an image array
    shape = createImageF(numPoints, 2)
    for p in range(0, numPoints):
        y, x = (mainSegmentAverage[p])[0], (mainSegmentAverage[p])[1]
        shape[0, p] = y - centre[0]
        shape[1, p] = x - centre[1]

    return centre, shape, width, height
Example #6
0
def reconstruction(coefficients):
    # Maximum frequency
    maxFrequencyH = int((len(coefficients) - 1) / 2)
    maxFrequencyW = int((len(coefficients[0]) - 1) / 2)

    height = 2 * maxFrequencyH
    width = 2 * maxFrequencyW

    # Adjust the size of the data to be even
    m = float(width)
    n = float(height)
    if width % 2 == 0:
        m = width + 1
    if height % 2 == 0:
        n = height + 1

    # Fundamental frequency
    ww = (2.0 * pi) / float(m)
    wh = (2.0 * pi) / float(n)

    reconstructionImage = createImageF(m, n)
    for x in range(0, width):
        printProgress(x, width - 1)
        for y in range(0, height):
            for kw,kh in itertools.product(range(-maxFrequencyW, maxFrequencyW + 1),             \
                                           range(-maxFrequencyH, maxFrequencyH + 1)):
                indexInArrayW = kw + maxFrequencyW
                indexInArrayH = kh + maxFrequencyH
                reconstructionImage[y,x] += \
                        (coefficients[indexInArrayH, indexInArrayW][0] / (m*n)) * (cos(x * ww * kw) * cos(y * wh * kh) - sin(x * ww * kw) * sin(y * wh * kh)) + \
                        (coefficients[indexInArrayH, indexInArrayW][1] / (m*n)) * (cos(x * ww * kw) * sin(y * wh * kh) + sin(x * ww * kw) * cos(y * wh * kh))

    return reconstructionImage
def createLaplacianKernel(kernelSize, sigma):

    # 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]

    # Normalize
    for x, y in itertools.product(range(0, kernelSize), range(0, kernelSize)):
        kernelLaplacian[y, x] /= sumValues

    return kernelLaplacian
def applyKernelF(inputImage, kernelImage):
    height = len(inputImage)
    width = len(inputImage[0])

    kernelHeight = len(kernelImage)
    kernelWidth = len(kernelImage[0])

    kernelCentreY = int((kernelHeight - 1) / 2)
    kernelCentreX = int((kernelWidth - 1) / 2)

    # Create images to store the result
    outputImage = createImageF(width, height)

    for x, y in itertools.product(range(0, width), range(0, height)):
        sumKernel = 0.0
        sumKernelWeights = 0.0
        for wx, wy in itertools.product(range(0, kernelWidth),
                                        range(0, kernelHeight)):
            posY = y + wy - kernelCentreY
            posX = x + wx - kernelCentreX

            if posY > -1 and posY < height and posX > -1 and posX < width:
                sumKernel += float(inputImage[posY, posX]) * float(
                    kernelImage[wy, wx])
                sumKernelWeights += float(kernelImage[wy, wx])

        # If we have to normalize
        if sumKernelWeights != 0.0:
            outputImage[y, x] = sumKernel / sumKernelWeights
        else:
            outputImage[y, x] = sumKernel

    return outputImage
Example #9
0
def densityHistogram(image, position, regionRadius, sigma, histoSize):
    height = len(image)
    width = len(image[0])

    # Quantization scale
    colourScale = 256.0 / histoSize

    histogram = createImageF(histoSize, histoSize)
    sumValue = 0
    for deltaX, deltaY in itertools.product(
            range(-regionRadius[0], regionRadius[0]),
            range(-regionRadius[1], regionRadius[1])):

        x, y = position[0] + deltaX, position[1] + deltaY
        if x > 0 and y > 0 and x < width and y < height:

            w = exp(-(deltaX * deltaX + deltaY * deltaY) / (2 * sigma * sigma))
            rgb = image[y, x] / 256.0

            Cb = int((128 - 37.79 * rgb[0] - 74.203 * rgb[1] + 112 * rgb[2]) /
                     colourScale)
            Cr = int((128 + 112 * rgb[0] - 93.786 * rgb[1] - 18.214 * rgb[2]) /
                     colourScale)

            histogram[Cr, Cb] += w
            sumValue += w

    for r, b in itertools.product(range(0, histoSize), range(0, histoSize)):
        histogram[r, b] /= sumValue

    return histogram
def createSobelKernel(kenrelSize):

    sobelX = createImageF(kenrelSize, kenrelSize)
    sobelY = createImageF(kenrelSize, kenrelSize)

    # Create kernel
    for x, y in itertools.product(range(0, kenrelSize), range(0, kenrelSize)):

        # Smooth
        smoothX = factorial(kenrelSize - 1) / (factorial(kenrelSize - 1 - x) *
                                               factorial(x))
        smoothY = factorial(kenrelSize - 1) / (factorial(kenrelSize - 1 - y) *
                                               factorial(y))

        # Pascal
        if (kenrelSize - 2 - x >= 0):
            p1X = factorial(kenrelSize - 2) / (factorial(kenrelSize - 2 - x) *
                                               factorial(x))
        else:
            p1X = 0

        if (kenrelSize - 2 - y >= 0):
            p1Y = factorial(kenrelSize - 2) / (factorial(kenrelSize - 2 - y) *
                                               factorial(y))
        else:
            p1Y = 0

        # Pascal shift to the right
        xp = x - 1
        if (kenrelSize - 2 - xp >= 0 and xp >= 0):
            p2X = factorial(kenrelSize - 2) / (factorial(kenrelSize - 2 - xp) *
                                               factorial(xp))
        else:
            p2X = 0

        yp = y - 1
        if (kenrelSize - 2 - yp >= 0 and yp >= 0):
            p2Y = factorial(kenrelSize - 2) / (factorial(kenrelSize - 2 - yp) *
                                               factorial(yp))
        else:
            p2Y = 0

        # Sobel
        sobelX[y, x] = smoothX * (p1Y - p2Y)
        sobelY[y, x] = smoothY * (p1X - p2X)

    return sobelX, sobelY
Example #11
0
def meanShift(inputImage, q, sizeReg, sigma, histoSize, newPos):
    # Weights
    weights = createImageF(2 * sizeReg[0], 2 * sizeReg[1])

    currPos = [0, 0]

    colourScale = 256.0 / histoSize

    while (currPos != newPos):
        currPos = newPos
        qs = densityHistogram(inputImage, currPos, sizeReg, sigma, histoSize)

        # Weights
        for deltaX, deltaY in itertools.product(range(-sizeReg[0],sizeReg[0]),   \
                                                range(-sizeReg[1], sizeReg[1])):

            # Position of the pixel in the image and in the weight array
            x, y = currPos[0] + deltaX, currPos[1] + deltaY
            px, py = deltaX + sizeReg[0], deltaY + sizeReg[1]

            # Features
            Cb, Cr = colourFeature(inputImage[y, x], colourScale)

            # Update
            if qs[Cr, Cb] > 0:
                weights[py, px] = sqrt(q[Cr, Cb] / qs[Cr, Cb])
            else:
                weights[py, px] = sqrt(q[Cr, Cb] / .000000000001)

        # Compute mean shift sums
        meanSum = [0, 0]
        kernelSum = 0
        for deltaX, deltaY in itertools.product(range(-sizeReg[0],sizeReg[0]),   \
                                                range(-sizeReg[1], sizeReg[1])):

            # Position of the pixel in the image
            x, y = currPos[0] + deltaX, currPos[1] + deltaY

            # Kernel parameter
            w = exp(-(deltaX * deltaX + deltaY * deltaY) / (2 * sigma * sigma))

            # Weight index
            px, py = deltaX + sizeReg[0], deltaY + sizeReg[1]

            # Mean sum
            meanSum[0] += w * weights[py, px] * x
            meanSum[1] += w * weights[py, px] * y

            # Kernel sum
            kernelSum += w * weights[py, px]

        # Mean shift
        newPos = [int(meanSum[0] / kernelSum), int(meanSum[1] / kernelSum)]

    return newPos
def createGaussianKernel(kernelSize):

    sigma = kernelSize / 3.0

    kernelImage = createImageF(kernelSize, kernelSize)
    centre = (kernelSize - 1) / 2
    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)) )

    return kernelImage
Example #13
0
def backProjectionImage(image, q, histoSize):
    height, width = len(image), len(image[0])
    colourScale = 256.0 / histoSize

    # Projection
    projection = createImageF(width, height)
    for x, y in itertools.product(range(0, width), range(0, height)):

        Cb, Cr = colourFeature(image[y, x], colourScale)
        projection[y, x] = q[Cr, Cb]

    return projection
Example #14
0
def geometricMoments(pixelList, numMoments):
    numPoints = len(pixelList)

    # Compute moments
    M = createImageF(numMoments, numMoments)
    for m, n in itertools.product(range(0, numMoments), range(0, numMoments)):
        for indexPixel in range(0, numPoints):
            y = (pixelList[indexPixel])[0]
            x = (pixelList[indexPixel])[1]
            val = (pixelList[indexPixel])[2]
            M[n, m] += (x**n) * (y**m) * val

    return M
Example #15
0
def geometricInvariantMoments(pixelList, numMoments):
    numPoints = len(pixelList)

    # Compute moments
    M = createImageF(numMoments, numMoments)
    for m, n in itertools.product(range(0, numMoments), range(0, numMoments)):
        for indexPixel in range(0, numPoints):
            y = (pixelList[indexPixel])[0]
            x = (pixelList[indexPixel])[1]
            val = (pixelList[indexPixel])[2]
            M[n, m] += (x**n) * (y**m) * val

    # Geometric central Moments
    xc, yc = M[1, 0] / M[0, 0], M[0, 1] / M[0, 0]

    m11 = M[1, 1] / M[0, 0] - xc * yc
    m20 = M[2, 0] / M[0, 0] - xc**2
    m02 = M[0, 2] / M[0, 0] - yc**2

    if m20 < m02:
        t = -(0.5 * atan(2.0 * m11 / (m20 - m02)) + pi / 2.0)
    else:
        t = -(0.5 * atan(2.0 * m11 / (m20 - m02)))

    # Geometric invariant moments
    v = createImageF(numMoments, numMoments)
    vn = createImageF(numMoments, numMoments)
    for m, n in itertools.product(range(0, numMoments), range(0, numMoments)):
        for indexPixel in range(0, numPoints):
            y = (pixelList[indexPixel])[0]
            x = (pixelList[indexPixel])[1]
            val = (pixelList[indexPixel])[2]
            v[n, m] += ((x - xc) * cos(t) -
                        (y - yc) * sin(t))**n * ((x - xc) * sin(t) +
                                                 (y - yc) * cos(t))**m * val
        l = (1 + ((n + m) / 2.0))
        vn[n, m] = v[n, m] / pow(M[0, 0], l)

    return vn
def imageLogF(image, scale=100):
    height = len(image)
    width = len(image[0])

    maximum = amax(image)

    # Create a gray level image for display
    logImage = createImageF(width, height)

    # Scale the float values into gray scale values without 0 and negative values
    for y in range(0, height):
        for x in range(0, width):
            # Set to log value
            logImage[y, x] = log(1.0 + (abs(image[y, x]) / maximum) * scale)

    return logImage
Example #17
0
def computeCoefficients(inputImage):
    height = len(inputImage)
    width = len(inputImage[0])

    # Create coefficients Image. Two floats to represent a complex number
    # Maximum frequency according to sampling
    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
    if height % 2 == 0:
        n = height + 1

    # Fundamental frequency
    ww = (2.0 * pi) / float(m)
    wh = (2.0 * pi) / float(n)

    # Compute values
    for kw in range(-maxFrequencyW, maxFrequencyW + 1):
        printProgress(kw + maxFrequencyW, numCoefficientsW - 1)
        for kh in range(-maxFrequencyH, maxFrequencyH + 1):
            indexInArrayW = kw + maxFrequencyW
            indexInArrayH = kh + maxFrequencyH

            for x, y in itertools.product(range(0, width), range(0, height)):
                coefficients[indexInArrayH,
                             indexInArrayW][0] += inputImage[y, x] * (
                                 cos(x * ww * kw) * cos(y * wh * kh) -
                                 sin(x * ww * kw) * sin(y * wh * kh))
                coefficients[indexInArrayH,
                             indexInArrayW][1] += inputImage[y, x] * (
                                 cos(x * ww * kw) * sin(y * wh * kh) +
                                 sin(x * ww * kw) * cos(y * wh * kh))

    for kw in range(-maxFrequencyW, maxFrequencyW + 1):
        for kh in range(-maxFrequencyH, maxFrequencyH + 1):
            coefficients[indexInArrayH, indexInArrayW][0] /= (m * n)
            coefficients[indexInArrayH, indexInArrayW][1] /= (m * n)

    return coefficients, maxFrequencyW, maxFrequencyH
Example #18
0
def computePowerfromCoefficients(coefficients):
    # Maximum frequency
    maxFrequencyH = int((len(coefficients) - 1) / 2)
    maxFrequencyW = int((len(coefficients[0]) - 1) / 2)

    # Power
    powerImage = createImageF(1 + 2 * maxFrequencyW, 1 + 2 * maxFrequencyH)

    for kw in range(-maxFrequencyW, maxFrequencyW + 1):
        printProgress(kw + maxFrequencyW, 2 * maxFrequencyW)
        for kh in range(-maxFrequencyH, maxFrequencyH + 1):
            indexInArrayW = kw + maxFrequencyW
            indexInArrayH = kh + maxFrequencyH
            powerImage[indexInArrayH, indexInArrayW] = sqrt(coefficients[indexInArrayH, indexInArrayW][0] * coefficients[indexInArrayH, indexInArrayW][0] + \
                                                            coefficients[indexInArrayH, indexInArrayW][1] * coefficients[indexInArrayH, indexInArrayW][1])

    return powerImage
Example #19
0
def findLongesSegmentinImage(imageName, gaussianKernelSize, sobelKernelSize,
                             upperT, lowerT):
    # Read image into array and show
    inputImage, width, height = imageReadL(imageName)

    # Compute edges and find the segment in the image
    magnitude, _ = applyCannyEdgeDetector(inputImage, gaussianKernelSize,
                                          sobelKernelSize, upperT, lowerT)
    mainSegmentAverage = findLongestSegment(magnitude)

    # Convert to an image array
    numPoints = len(mainSegmentAverage)
    shape = createImageF(numPoints, 2)
    for p in range(0, numPoints):
        y, x = (mainSegmentAverage[p])[0], (mainSegmentAverage[p])[1]
        shape[0, p] = y
        shape[1, p] = x

    return shape, width, height
Example #20
0
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
def applyCannyEdgeDetector(inputImage,
                           GaussianKernelSize,
                           sobelKernelSize,
                           upperT,
                           lowerT,
                           returnGradient=False):

    height = len(inputImage)
    width = len(inputImage[0])

    normalizeMagnitude = True
    windowDelta = 1

    # 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, mX, mY = applyKernelMA(gaussianImage, sobelX, sobelY,
                                             normalizeMagnitude)

    # Weight magnitude by the variance. This is useful for corner extraction since suppress the internal corner
    weightedMagnitude = createImageF(width, height)
    for x, y in itertools.product(range(0, width), range(0, height)):
        sumKernel = 1.0 / 8.0
        for wx, wy in itertools.product(range(-1, 2), range(-1, 2)):

            posY = y + wy
            posX = x + wx

            if posY > -1 and posY < height and posX > -1 and posX < width:
                sumKernel += abs(
                    float(inputImage[posY, posX]) - float(inputImage[y, x]))

        sumKernel /= 8.0
        weightedMagnitude[y, x] = magnitude[y, x] * sumKernel

    # 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:
                normalAngle -= pi

            # Angle defining the first point
            baseAngle = int(4 * normalAngle / pi) * (pi / 4.0)

            # Integer delta positions for interpolation
            # We use -y since the image origin is in top corner
            x1, y1 = int(round(cos(baseAngle))), -int(round(sin(baseAngle)))
            x2, y2 = int(round(cos(baseAngle + pi / 4.0))),                     \
                    -int(round(sin(baseAngle + pi / 4.0)))

            # How far we are from (x1,y1). Maximum difference is math.pi / 4.0, so we multiply by 2
            w = cos(2.0 * (normalAngle - baseAngle))

            # Point to interpolate
            M1 = w * weightedMagnitude[y + y1, x + x1] + (
                1.0 - w) * weightedMagnitude[y + y2, x + x2]

            # Point to interpolate for pixels in the other side of the edge
            M2 = w * weightedMagnitude[y - y1, x - x1] + (
                1.0 - w) * weightedMagnitude[y - y2, x - x2]

            # Determine if it is a maximum. If so make sure it will be preserved
            if weightedMagnitude[y, x] > M1 and weightedMagnitude[y, x] > M2:
                maxImage[y, x] = magnitude[y, x]

    # To compute hysteresis thresholded images we require two thresholds
    edges = createImageF(width, height)
    potentialEdges = []

    # Divide pixels as edges, no edges and we are not sure
    for x, y in itertools.product(range(1, width - 1), range(1, height - 1)):
        # These are edges
        if maxImage[y, x] > upperT:
            edges[y, x] = 255

        # These are pixels that we do not want as edges
        if maxImage[y, x] < lowerT:
            edges[y, x] = 0

        # These may be edges
        if maxImage[y, x] > lowerT and maxImage[y, x] <= upperT:
            edges[y, x] = 128

    # Resolve the potential edges
    for x, y in itertools.product(range(1, width - 1), range(1, height - 1)):
        # For each edge
        if edges[y, x] == 255:

            # Examine neighbour
            potentialEdges = []
            for wx, wy in itertools.product(
                    range(-windowDelta, windowDelta + 1),
                    range(-windowDelta, windowDelta + 1)):
                # It becomes an edge
                if edges[y + wy, x + wx] == 128:
                    edges[y + wy, x + wx] = 255
                    potentialEdges.append((y + wy, x + wx))

            # Look into new edges
            while len(potentialEdges) > 0:
                # Take element from potential edges
                y = (potentialEdges[0])[0]
                x = (potentialEdges[0])[1]
                potentialEdges = potentialEdges[1:]

                # Examine neighbour
                for wx, wy in itertools.product(
                        range(-windowDelta, windowDelta + 1),
                        range(-windowDelta, windowDelta + 1)):
                    # It becomes an edge
                    if edges[y + wy, x + wx] == 128:
                        edges[y + wy, x + wx] = 255
                        potentialEdges.append((y + wy, x + wx))

    # Clean up remaining potential edges
    for x, y in itertools.product(range(1, width - 1), range(1, height - 1)):
        if edges[y, x] == 128:
            edges[y, x] = 0

    if returnGradient == False:
        return edges, angle

    return edges, angle, mX, mY
Example #22
0
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