예제 #1
0
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
예제 #2
0
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)))

# Compute sx, sy, the size of the projection in current frame
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)))

# Determine size of the region in current frame
sy = int(sy * sizeReg[1] / syS)
sx = int(sx * sizeReg[0] / sxS)

# Show results
p = [int(xc), int(yc)]
m, _ = imageMaxMin(projectionTarget)
borderDistance = [sx - 2, sy - 2]
for x, y in itertools.product(range(p[0] - sx, p[0] + sx),                 \
                              range(p[1] - sy, p[1] + sy)):

    if abs(x - p[0]) > borderDistance[0] or abs(y - p[1]) > borderDistance[1]:
        projectionTarget[y, x] = m

showImageF(projectionTarget)
# Create an accumulator. We look in a reduced size image
accumulator = createImageF(width, height)
  
# Template matching
templateCentreX = int((widthTemplate - 1) / 2)
templateCentreY = int((heightTemplate - 1) / 2)
for x in range(0, width):  
    printProgress(x, width)
    for y in range(0, height):
        for wx,wy in itertools.product(range(0, widthTemplate), range(0, heightTemplate)):
            posY = y + wy - templateCentreY
            posX = x + wx - templateCentreX 
            
            # The threshold is used to accumulate only the edge pixels in an edge template
            # The difference of pixel values is inverted to show the best match as a peak
            if posY > -1 and posY <  height and  posX > -1 and posX <  width and            \
               templateImage[wy,wx] > thresholdVal:
                diff = 1.0 - abs(float(inputImage[posY,posX]) -                             \
                                 float(templateImage[wy, wx])) / 255.0
                
                accumulator[y,x] += diff*diff 
                        
# Show accumulator within a maxima and mininma region
maxima, minima = imageMaxMin(accumulator)
showImageF(accumulator)
plot3DHistogram(accumulator, [minima, maxima])




예제 #4
0
                    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:
                    watershed[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 watershed[y, x] == 0:
        floodRegion.append((y, x))

# 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:
                n = []  #  List of neighbours
    imageName = Input image name
'''
pathToDir = "../../Images/Chapter3/Input/"
imageName = "Horse.png"

# Read image into array
inputImage, width, height = imageReadL(pathToDir + imageName)

# Show input image
showImageL(inputImage)

# Create image to store the normalization
outputNormalizedImage = createImageL(width, height)

# Maximum and range
maxVal, miniVal = imageMaxMin(inputImage)
brightRange = float(maxVal - miniVal)

# Set the pixels in the output image
for x, y in itertools.product(range(0, width), range(0, height)):

    # Normalize the pixel value according to the range
    outputNormalizedImage[y, x] = round(
        (inputImage[y, x] - miniVal) * 255.0 / brightRange)

# Compute histogram
histogramNormalizedImage = computeHistogram(outputNormalizedImage)

# Show output image and plot histogram
showImageL(outputNormalizedImage)
plotHistogram(histogramNormalizedImage)
            if bucket > 0 and bucket < 2 * height - 1:
                weight = c - int(c)
                accHorizontal[m, bucket] += (1.0 - weight)
                accHorizontal[m, bucket + 1] += weight

            # Lines between 45 and 135 degrees
            angle = ((45.0 + m) * pi) / 180.0
            c = x - y / tan(angle)
            bucket = int(c)
            if bucket > 0 and bucket < 2 * width - 1:
                weight = c - int(c)
                accVertical[m, bucket] += (1.0 - weight)
                accVertical[m, bucket + 1] += weight

# Find maximum
maxH, _ = imageMaxMin(accHorizontal)
maxV, _ = imageMaxMin(accVertical)
maximum = max(maxH, maxV)
peakThreshold = peakDetection * maximum

# Plot accumulators
plot3DHistogram(accHorizontal, [0, maximum])
plot3DHistogram(accVertical, [0, maximum])

# Prepare output image as a dark version of the input
outputImage = createScaleImageL(inputImage, 0.5)

# Peak detection
peakHorizontal = peakDetectorImageL(accHorizontal, peakThreshold)
peakVertical = peakDetectorImageL(accVertical, peakThreshold)
for x, y in itertools.product(range(0, widthPad), range(0, heightPad)):
    for w,h in itertools.product(range(-widthTemplate+1,1),                         \
                                 range(-heightTemplate+1,1)):
        p, q = x + w, y + h
        if p >= 0 and q >= 0 and p < width and q < height:
            squaredTerm[y, x] += inputPad[q, p] * inputPad[q, p]
            corrImage[y, x] += 2.0 * templatePad[h + heightTemplate - 1,
                                                 w + widthTemplate -
                                                 1] * inputPad[q, p]

if addQuadraticTerm:
    for x, y in itertools.product(range(0, widthPad), range(0, heightPad)):
        corrImage[y, x] += -squaredTerm[y, x]

showImageF(corrImage)
maxima, minima = imageMaxMin(corrImage)
plot3DHistogram(corrImage, [2 * (minima + maxima) / 3, maxima], [15, -47],
                False)

# Compute Fourier coefficients
imageCoeff, maxFrequencyW, maxFrequencyH = computeCoefficients(inputPad)
templateCoeff, _, _ = computeCoefficients(templatePadFlip)

# Frequency domain multiplication defines convolution is space domain
resultCoeff = createImageF(1 + 2 * maxFrequencyW, 1 + 2 * maxFrequencyH, 2)
for kw, kh in itertools.product(range(-maxFrequencyW, maxFrequencyW + 1),         \
                                range(-maxFrequencyH, maxFrequencyH + 1)):
    w = kw + maxFrequencyW
    h = kh + maxFrequencyH
    resultCoeff[h,w][0] = (imageCoeff[h,w][0] * templateCoeff[h,w][0] -           \
                           imageCoeff[h,w][1] * templateCoeff[h,w][1])
예제 #8
0
                    buketAngleBase = int((pointAngle * 180.0) / pi)

                    # More buckets if the points are close
                    for deltaBucket in range(-incAngle, +incAngle + 1):
                        bucket = buketAngleBase + deltaBucket
                        if bucket < 0:
                            bucket = 360 + bucket
                        if bucket >= 360:
                            bucket = bucket - 360

                        w = (incAngle - fabs(deltaBucket)) / float(incAngle)
                        accM[bucket] += w

# Find maximum and plot histogram
maximum, _ = imageMaxMin(accM)
peakThreshold = peakDetection * maximum
plotHistogram(accM)

# Prepare output image as a dark version of the input
outputImage = createScaleImageL(inputImage, 0.5)

# Gather evidence for the r parameter in a second accumulator
peaks = peakDetectorVector(accM, peakThreshold)
for peakIndex in range(0, len(peaks)):
    m = peaks[peakIndex]

    accR = createVectorF(maxLenght)
    angle = (m * pi) / 180.0
    for x, y in itertools.product(range(0, width), range(0, height)):
        if magnitude[y, x] != 0:
예제 #9
0
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

# Find maximum
maximum, _ = imageMaxMin(accumulator)
peakThreshold = peakDetection * maximum

# Plot accumulator
plot3DHistogram(accumulator)

# Prepare output image as a dark version of the input
outputImage = createScaleImageL(inputImage, 0.5)

# Peak detection
peaks = peakDetectorImageL(accumulator, peakThreshold)

# Draw lines on output image
for peakIndex in range(1, len(peaks)):
    m = (peaks[peakIndex])[0]
    r = (peaks[peakIndex])[1]
예제 #10
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
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]

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

# Print kernel
printImageRangeF(kernelLaplacian, [0, kernelSize - 1], [0, kernelSize - 1],
                 ' 8.2f')

# Plot surface
maxValue, minValue = imageMaxMin(kernelLaplacian)
plotSurface(kernelLaplacian, [minValue, maxValue], 1)
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)