lowerT = 0.05 numEntries = 90 # Read image into array and show templateImage, widthTemplate, heightTemplate = imageReadL(pathToDir + templateName) inputImage, width, height = imageReadL(pathToDir + imageName) showImageL(templateImage) showImageL(inputImage) # Compute edges magnitudeTemplate, angleTemplate = applyCannyEdgeDetector( templateImage, gaussianKernelSize, sobelKernelSize, upperT, lowerT) magnitude, angle = applyCannyEdgeDetector(inputImage, gaussianKernelSize, sobelKernelSize, upperT, lowerT) showImageF(magnitudeTemplate) showImageF(magnitude) # Compute reference point in the template refPoint = [0, 0] edgePoints = [] for x, y in itertools.product(range(0, widthTemplate), range(0, heightTemplate)): if magnitudeTemplate[y, x] != 0: refPoint[0] += y refPoint[1] += x edgePoints.append((y, x)) numPts = len(edgePoints) refPoint = [int(refPoint[0] / numPts), int(refPoint[1] / numPts)] # Build Rtable as a list of lists
pathToDir = "../../Images/Chapter8/Input/" imageName = "Logs.png" cannyKernelSize = 7 upperT = 0.5 lowerT = 0.1 windowDelta = 3 suppWindow = 5 # Read image into array and show inputImage, width, height = imageReadL(pathToDir + imageName) showImageL(inputImage) # Compute edges magnitude, angle = applyCannyEdgeDetector(inputImage, cannyKernelSize, cannyKernelSize, upperT, lowerT) showImageF(magnitude) # Divide pixels into edge and region pixels edgePixels = [] shapeImage = [] for x, y in itertools.product(range(0, width), range(0, height)): if magnitude[y, x] > 0: edgePixels.append((y, x)) shapeImage.append((y, x)) # Radial is the minimal distance to the edge distanceImage = createImageF(width, height) numEdges = len(edgePixels) for x in range(0, width): printProgress(x, width) for y in range(0, height):
coeff[entryH, entryW][1] *= m * n # Reconstruction reconstruction = createImageF(width, height) for u in range(-maxFreqW, maxFreqW + 1): printProgress(u + maxFreqW, numCoeffW) entryW = u + maxFreqW for v in range(-maxFreqH, maxFreqH + 1): entryH = v + maxFreqH for x in range(0, width): for y in range(0, height): reconstruction[y,x] += (coeff[entryH, entryW][0] / (m*n)) * (cos(x * ww * u) * cos(y * wh * v) - sin(x * ww * u) * sin(y * wh * v)) - \ (coeff[entryH, entryW][1] / (m*n)) * (cos(x * ww * u) * sin(y * wh * v) + sin(x * ww * u) * cos(y * wh * v)) showImageF(reconstruction) # Power power = createImageF(1 + 2 * maxFreqW, 1 + 2 * maxFreqH) for kw, kh in itertools.product(range(-maxFreqW, maxFreqW + 1), range(-maxFreqH, maxFreqH + 1)): entryW = kw + maxFreqW entryH = kh + maxFreqH power[entryH, entryW] = sqrt(coeff[entryH, entryW][0] * coeff[entryH, entryW][0] + \ coeff[entryH, entryW][1] * coeff[entryH, entryW][1]) power[entryH, entryW] = log(1.0 + power[entryH, entryW]) # Show the log of the power powerLog = imageLogF(power) showImageF(powerLog)
mYx = applyKernelF(mY, sobelX) mYy = applyKernelF(mY, sobelY) # Compute curvature curvature = createImageF(width, height) for x, y in itertools.product(range(0, width), range(0, height)): # If it is an edge if magnitude[y, x] > 0: Mx2, My2, MxMy = mX[y, x] * mX[y, x], mY[y, x] * mY[y, x], mX[ y, x] * mY[y, x] if Mx2 + My2 != 0.0: p = 1.0 / pow((Mx2 + My2), 1.5) if op == "T": curvature[y,x] = p * (My2 * mXx[y,x] - MxMy * mYx[y,x] + \ Mx2 * mYy[y,x] - MxMy * mXy[y,x]) if op == "TI": curvature[y,x] = p * (-My2 * mXx[y,x] + MxMy * mYx[y,x] - \ Mx2 * mYy[y,x] + MxMy * mXy[y,x]) if op == "N": curvature[y,x] = p * (Mx2 * mYx[y,x] - MxMy * mYx[y,x] - \ MxMy * mYy[y,x] + My2 * mXy[y,x]) if op == "NI": curvature[y,x] = p * (-Mx2 * mYx[y,x] + MxMy * mXx[y,x] + \ MxMy * mYy[y,x] - My2 * mXy[y,x]) curvature[y, x] = fabs(curvature[y, x]) showImageF(curvature, 2)
# 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])
axisRange = [20, 65] angleRange = [0, 4] segmentLenghtThreshod = 0.20 pairsPerPoint = 30 # Sample points distance. Higher the eccentricity higher the distance so points give accurate positions axisRatio = float(axisRange[1]) / (2.0 * float(axisRange[0])) deltaPointRange = [int(axisRatio * axisRange[0]), int(1.2 * axisRange[1])] # Read image #49 20 0.03490658503988659 125 77 2 inputImage, width, height = imageReadL(pathToDir + imageName) # Compute edges magnitude, angle = applyCannyEdgeDetector(inputImage, gaussianKernelSize, sobelKernelSize, upperT, lowerT) showImageF(magnitude) # Find segments segmentsList = [] segmentsImage = createImageF(width, height) maxSegmentLenght = 0 for x, y in itertools.product(range(0, width), range(0, height)): if magnitude[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:]
# 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] # Power powerLow = computePowerfromCoefficients(coeffLow) powerHigh = computePowerfromCoefficients(coeffHigh) # Show power powerLowLog = imageLogF(powerLow) powerHighLog = imageLogF(powerHigh) showImageF(powerLowLog) showImageF(powerHighLog) # Reconstruct image imageLow = reconstruction(coeffLow) imageHigh = reconstruction(coeffHigh) showImageF(imageLow) showImageF(imageHigh)
# Get a list of edge pixels edgePixels = edgesList(inputImage, shapeImage, background) # Compute the radial distance to the edge distanceImage = createImageF(width, height) numEdges = len(edgePixels) for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] minEdgeDist = FLT_MAX for indexEdge in range(0, numEdges): edgeY, edgeX = (edgePixels[indexEdge])[0], (edgePixels[indexEdge])[1] minEdgeDist = min(minEdgeDist, sqrt((edgeX - x)**2 + (edgeY - y)**2)) distanceImage[y, x] = minEdgeDist # Show distance showImageF(distanceImage) # Watershed image watershed = createImageF(width, height) # Initial regions by finding the maximum suppWindow = 5 # Window used to find a maximum regionIndex = 1 # Start id for a region for indexPixel in range(0, numPoints): y, x = (shapeImage[indexPixel])[0], (shapeImage[indexPixel])[1] if watershed[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 watershed[wy, wx] != 0 or \
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) showImageF(vertEdges) showImageF(outputEdges)
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): printProgress(u + maxFreqW, numCoeffW) entryW = u + maxFreqW for v in range(-maxFreqH, maxFreqH + 1): entryH = v + maxFreqH for x, y in itertools.product(range(0, width), range(0, height)): coeff[entryH, entryW] += inputImage[y,x] * \ (cos(x * ww * u) + sin(x * ww * u)) * (cos(y * wh * v) + sin(y * wh * v)) # Include scale for u in range(-maxFreqW, maxFreqW + 1): printProgress(u + maxFreqW, numCoeffW) entryW = u + maxFreqW for v in range(-maxFreqH, maxFreqH + 1): entryH = v + maxFreqH coeff[entryH, entryW] /= m * n # Show transform in log form. The function converts negative values to positive, # so it is similar to the power coeffLog = imageLogF(coeff) showImageF(coeffLog)
# Create Kernel kernelLaplacian = createLaplacianKernel(kernelSize, sigma) # Apply kernel gaussianImage = applyKernelF(inputImage, kernelLaplacian) # Zero-crossing detector edges = createImageL(width, height) kernelCentre = int((kernelSize - 1) / 2) for x, y in itertools.product(range(1, width - 1), range(1, height - 1)): quadrantValue = [0.0, 0.0, 0.0, 0.0] for wx, wy in itertools.product(range(-1, 1), range(-1, 1)): quadrantValue[0] += gaussianImage[y + wy, x + wx] for wx, wy in itertools.product(range(-1, 1), range(0, 2)): quadrantValue[1] += gaussianImage[y + wy, x + wx] for wx, wy in itertools.product(range(0, 2), range(-1, 1)): quadrantValue[2] += gaussianImage[y + wy, x + wx] for wx, wy in itertools.product(range(0, 2), range(0, 2)): quadrantValue[3] += gaussianImage[y + wy, x + wx] maxVal, minVal = max(quadrantValue), min(quadrantValue) if maxVal > 0.0 and minVal < 0: edges[y, x] = 255 showImageF(gaussianImage) showImageL(edges)
''' 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 printImageRangeF(outputDirection, [0, width - 1], [0, height - 1]) # Plot vectors plotQuiver(outputMagnitude, outputDirection, 1300)
for wx, wy in itertools.product(range(0, kernelSize), range(0, kernelSize)): posY = y + wy - kernelCentre posX = x + wx - kernelCentre if posY > -1 and posY < height and posX > -1 and posX < width: mX += float(inputImage[posY, posX]) * sobelX[wy, wx] wX += sobelX[wy, wx] mY += float(inputImage[posY, posX]) * sobelY[wy, wx] wY += sobelY[wy, wx] if wX > 0: mX = mX / wX if wY > 0: mY = mY / wY outputMagnitude[y, x] = sqrt(mX * mX + mY * mY) outputDirection[y, x] = atan2(mY, mX) # Threshold image outputthresholdMagnitude = thresholdImage(outputMagnitude, threshold, True) # Show output image showImageF(outputMagnitude) showImageL(outputthresholdMagnitude) # Plot scaled vectors plotQuiver(outputMagnitude, outputDirection, quiverScale, quiverSample)
for x,y in itertools.product(range(0, kernelSize), range(0, kernelSize)): kernelImage[y, x] = 255.0 # Padding size widthPad, heightPad = width+kernelSize-1, height+kernelSize-1 # Padding input inputPad = createImageF(widthPad, heightPad) for x,y in itertools.product(range(0, width), range(0, height)): inputPad[y,x] = inputImage[y,x] # Padding and flip template templatePadFlip = createImageF(widthPad, heightPad) for x,y in itertools.product(range(0, kernelSize), range(0, kernelSize)): templatePadFlip[y, x] = kernelImage[kernelSize-y-1, kernelSize-x-1] showImageF(templatePadFlip) # Compute coefficients imageCoeff, maxFrequencyW, maxFrequencyH = computeCoefficients(inputPad) templateCoeff, _, _ = computeCoefficients(templatePadFlip) # Show the log of the power of the input image and template powerImage = computePowerfromCoefficients(imageCoeff) powerImageLog = imageLogF(powerImage) showImageF(powerImageLog) powerTemplate = computePowerfromCoefficients(templateCoeff) powerTemplateLog = imageLogF(powerTemplate) showImageF(powerTemplateLog) # Frequency domain multiplication
coefficients[indexInArrayH, indexInArrayW][1] *= m * n # Power power = createImageF(1 + 2 * maxFrequencyW, 1 + 2 * maxFrequencyH) for kw,kh in itertools.product(range(-maxFrequencyW, maxFrequencyW + 1), \ range(-maxFrequencyH, maxFrequencyH + 1)): indexInArrayW = kw + maxFrequencyW indexInArrayH = kh + maxFrequencyH power[indexInArrayH, indexInArrayW] = \ sqrt(coefficients[indexInArrayH, indexInArrayW][0] * \ coefficients[indexInArrayH, indexInArrayW][0] + \ coefficients[indexInArrayH, indexInArrayW][1] * \ coefficients[indexInArrayH, indexInArrayW][1]) # Show the log of the power powerLog = imageLogF(power) showImageF(powerLog) # Phase phase = createImageF(1 + 2 * maxFrequencyW, 1 + 2 * maxFrequencyH) for kw,kh in itertools.product(range(-maxFrequencyW, maxFrequencyW + 1), \ range(-maxFrequencyH, maxFrequencyH + 1)): indexInArrayW = kw + maxFrequencyW indexInArrayH = kh + maxFrequencyH phase[indexInArrayH, indexInArrayW] = \ atan2(coefficients[indexInArrayH, indexInArrayW][1], \ coefficients[indexInArrayH, indexInArrayW][0]) # Show phase showImageF(phase)
# Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Shift the image shiftDistance = int(width / 3); shiftImage = createImageL(width, height) for x,y in itertools.product(range(0, width), range(0, height)): xShift = (x - shiftDistance) % width shiftImage[y][x] = inputImage[y][xShift] # Show images showImageL(inputImage) showImageL(shiftImage) # Compute power and phase powerImage, phaseImage = computePowerandPhase(inputImage) powerShiftImage, phaseShiftImage = computePowerandPhase(shiftImage) # Show power powerImageLog = imageLogF(powerImage) powerShiftImageLog = imageLogF(powerShiftImage) showImageF(powerImageLog) showImageF(powerShiftImageLog) # show phase showImageF(phaseImage) showImageF(phaseShiftImage)
# 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) # Compute correlation in image domain sum of square differences squaredTerm = createImageF(widthPad, heightPad) corrImage = createImageF(widthPad, heightPad) 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]
for iteration in range(0, numIterations): for x, y in itertools.product(range(0, width), range(0, height)): image[y, x] = outputImage[y, x] for x, y in itertools.product(range(0, width), range(0, height)): sumWeights = 0 outputImage[y, x] = 0 centrePixleValue = image[y, x] for wx, wy in itertools.product(range(0, kernelSize), range(0, kernelSize)): posY, posX = y + wy - kernelCentre, x + wx - kernelCentre if posY > -1 and posY < height and posX > -1 and posX < width: # Weight according to gradient weight = exp(-pow((image[posY, posX] - centrePixleValue) / k, 2)) # Use lambda to weight the pixel value if posY != y and posX != x: weight *= lamda sumWeights += weight outputImage[y, x] += weight * float(image[posY, posX]) # Normalize if sumWeights > 0: outputImage[y, x] /= sumWeights # Show output image showImageF(outputImage)
imageName = "Shapes.png" GaussianKernelSize = 7 sobelKernelSize = 3 upperT = 0.4 lowerT = 0.2 windowDelta = 2 # Read image into array inputImage, width, height = imageReadL(pathToDir + imageName) # Show input image showImageL(inputImage) # Compute edges magnitude, angle = applyCannyEdgeDetector(inputImage, GaussianKernelSize, sobelKernelSize, upperT, lowerT) showImageF(magnitude) # Compute curvature by subtracting the direction of neighbors curvature = createImageF(width, height) for x,y in itertools.product(range(0, width), range(0, height)): # Edge if magnitude[y,x] > 0: # Consider neighbor edges edgesNeigbor = [ ] for wx,wy in itertools.product(range(-windowDelta, windowDelta+1), \ range(-windowDelta, windowDelta+1)): if magnitude[y+wy, x+wx] > 0 : edgesNeigbor.append((y+wy,x+wx)) # Use dot product to measure angle difference np = len(edgesNeigbor)
#plot3DHistogram(q) # Projection by setting the pixel's value to the high in the histogram for # the source and target images colourScale = 256.0 / histoSize 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] = q[Cr, Cb] Cb, Cr = colourFeature(targetImage[y, x], colourScale) projectionTarget[y, x] = q[Cr, Cb] showImageF(projectionSource) showImageF(projectionTarget) # Compute geometric moments of the source and target image regions momS = createImageF(3, 3) momT = createImageF(3, 3) ps, pt = positions[0], positions[1] 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])): xs, ys = ps[0] + deltaX, ps[1] + deltaY xt, yt = pt[0] + deltaX, pt[1] + deltaY for m, n in itertools.product(range(0, 3), range(0, 3)): momS[n, m] += (xs**n) * (ys**m) * projectionSource[y, x] momT[n, m] += (xt**n) * (yt**m) * projectionTarget[y, x]
for wx, wy in itertools.product(range(px - 1, px + 2), range(py - 1, py + 2)): if wy >= 0 and wy < height and wx >= 0 and wx < width: if inputImage[wy, wx] <= threshold and regionsImage[ wy, wx] == 0: growRegion.append((wy, wx)) nextRegionID += 1 # Update times for regions for idRegion in incSizeRegions: # Update the size incSize = incSizeRegions[idRegion] sizeRegions[idRegion] += incSize # Update stable if incSize < incThreshold: timeRegions[idRegion] += 1 else: timeRegions[idRegion] = 0 # Stable region condition if timeRegions[idRegion] > timeThreshold and sizeRegions[ idRegion] > minRegionSize: for x, y in itertools.product(range(0, width), range(0, height)): if regionsImage[y, x] == idRegion: resultImage[y, x] = 255 timeRegions[idRegion] = 0 showImageF(resultImage)
GaussianKernelSize, sobelKernelSize, upperT, lowerT, True) \ # The center of the kernel kernelCentre = int((kernelSize - 1) / 2) # Compute curvature curvature = createImageF(width, height) for x,y in itertools.product(range(0, width), range(0, height)): # If it is an edge if magnitude[y,x] > 0: A, B, C = 0.0, 0.0, 0.0 for wx,wy in itertools.product(range(0, kernelSize), range(0, kernelSize)): posY = y + wy - kernelCentre posX = x + wx - kernelCentre if posY > -1 and posY < height and posX > -1 and posX < width: A += mX[posY,posX] * mX[posY,posX] B += mY[posY,posX] * mY[posY,posX] C += mX[posY,posX] * mY[posY,posX] if op == "H": curvature[y,x] = (A * B) - (C * C) - (k * ((A+B) * (A+B))) if op == "M": d = mX[y,x] * mX[y,x] + mY[y,x] * mY[y,x] if d != 0.0: curvature[y,x] = (A * mY[y,x] * mY[y,x] - \ 2.0 * C * mX[y,x] * mY[y,x] + \ B * mX[y,x] * mX[y,x]) / d showImageF(curvature)
# Maximum difference is pi / 4.0, so we multiply by 2 w = cos(2.0 * (normalAngle - baseAngle)) # Point to interpolate M1 = w * magnitude[y + y1, x + x1] + (1.0 - w) * magnitude[y + y2, x + x2] # Point to interpolate for pixels in the other side of the edge M2 = w * magnitude[y - y1, x - x1] + (1.0 - w) * magnitude[y - y2, x - x2] # Determine if it is a maximum. If so make sure it will be preserved if magnitude[y, x] > M1 and magnitude[y, x] > M2: maxImage[y, x] = magnitude[y, x] showImageF(maxImage) # To compute hysteresis thresholded images we require two thresholds edges = createImageF(width, height) potentialEdges = [] # Divide pixels as edges, no edges and unassigned 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