自炊でいちばんよく使う多目的Macroを、FijiのJython(Python)を用いてPluginにリメイクしました。ちょこっと新機能付き。
※ 2024/02/25 追記. いろいろアップデートしていましたが、ver 10.13.2でいちおう暫定的に完成です。余計な処理を省いたので、Autoの最適コントラスト値探査 (optMinMaxAuto) が爆速になりました。
旧マクロバージョン
imagej-jisui.hatenablog.com
もくじ
# Almighty_Processing_Remake.py
from ij import IJ, ImagePlus, ImageStack
from ij import WindowManager as WM
from ij.gui import GenericDialog, WaitForUserDialog, Roi, Toolbar
from ij.measure import ResultsTable
from ij.plugin import ChannelSplitter
from ij.plugin.filter import Convolver
from ij.plugin.frame import RoiManager
from ij.process import ImageProcessor, ByteProcessor, ColorProcessor
from java.awt.event import AdjustmentListener, ItemListener
import os
import shutil
import time
version = "10.16.0"
# 10.3.0 -> apply8bitRangeLUT
# 10.4.0 -> extractOnlyRedChannel
# 10.5.0 -> imp.resize
# 10.6.0 -> saveAs(imp,"JPEG",...)
# 10.7.0 -> sharpeningFilter
# 10.8.0 -> cropRect
# 10.9.0 -> ResultsTable (Output log)
# 10.10.0 -> input toBeCheckedFiles
# 10.11.0 -> Error handling of optMinMaxAuto to multiple directories
# 10.12.0 -> Resize for optAuto
# 10.13.0 -> Stop repetitive task of opening and closing imgs (optAuto)
# 10.14.0 -> Use B&C Window (mokushiNow)
# 10.15.0 -> getRoiNombre
# 10.16.0 -> Modify for Outlier Exclusion (optAuto)
IJ.log("")
IJ.log("Almighty Processing Remake")
IJ.log("ver" + version)
IJ.log("makeDirAuto + listFilesRecursively")
IJ.log("")
logWindow = WM.getFrame("Log") # prepare to bring to front
startTime = time.strftime("%Y-%m-%d %H:%M:%S")
#------------------------------------------------------------------------------
# Define getFileList
def getFileList(dir):
list = []
for filename in os.listdir(dir):
if os.path.isdir(os.path.join(dir, filename)):
if not filename.startswith("."):
filename += "/"
list.append(filename)
if os.path.isfile(os.path.join(dir, filename)):
if not filename.startswith("."):
list.append(filename)
list.sort()
return list
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define countFiles
def countFiles(dir):
global totalFiles
list = getFileList(dir)
for i in range(len(list)):
if list[i].endswith("/"):
countFiles(dir + list[i])
else:
totalFiles += 1
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define listFiles
def listFiles(dir):
list = getFileList(dir)
for i in range(len(list)):
if list[i].endswith("/"):
listFiles(dir + list[i])
else:
filepath = dir + list[i]
mainOpe(filepath)
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# define zeroPad
def zeroPad(number, length):
return str(int(number)).zfill(length)
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define getTimeStamp
def getTimeStamp():
timestamp = time.strftime("%Y%m%d_%Hh%Mm%Ss", time.localtime())
return timestamp
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define getElapsedTime
def getElapsedTime(initialTime,completionTime):
Time = completionTime - initialTime;
msec = Time % 1
msec = int(msec * 1000)
sec = int(Time % 60)
min = int(Time / 60) % 60
hour = int(Time / 3600)
strElapsedTime = zeroPad(hour, 2) + "h : " + zeroPad(min, 2) + "m : " + zeroPad(sec, 2) + "." + zeroPad(msec, 3) + "s"
return strElapsedTime
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#Define waitForUser
def waitForUser(msg):
WaitForUserDialog(msg).show()
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define getBoundingRect
def getBoundingRect(impA):
# Get ROI info
roi = impA.getRoi()
# Check ROI
if roi and isinstance(roi, Roi) and roi.getType() == Roi.RECTANGLE:
x = roi.getXBase()
y = roi.getYBase()
width = int(roi.getFloatWidth())
height = int(roi.getFloatHeight())
else:
IJ.showMessage("Error: Rectangle ROI not found.")
raise RuntimeError("yamepi")
return x, y, width, height
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define cropRect
def cropRect(impA):
"""" for [one image] or [RBG stack image] """
# Get ROI Info
x, y, width, height = getBoundingRect(impA)
# Crop section
if impA.getStackSize() == 1:
ip = impA.getProcessor()
roi = Roi(x, y, width, height)
impA.setRoi(roi)
# Crop image and construct new imp
new_ip = ip.crop()
new_imp = ImagePlus("Cropped Image", new_ip)
impA.changes = False
impA.close()
new_imp.changes = False
new_imp.close()
return new_imp
elif impA.getStackSize() == 3:
# Get stack from impA
stack = impA.getImageStack()
# Construct new stack
new_stack = ImageStack(width, height)
# Add slice to new stack
for i in range(1, stack.getSize() + 1):
ip = stack.getProcessor(i)
roi = Roi(x, y, width, height)
ip.setRoi(roi)
new_ip = ip.crop()
new_stack.addSlice(stack.getSliceLabel(i), new_ip)
# Construct new imp
new_imp = ImagePlus("Cropped RGB Stack", new_stack)
impA.changes = False
impA.close()
new_imp.changes = False
new_imp.close()
return new_imp
else:
IJ.showMessage("Not support this stack size")
raise RuntimeError("yamepi")
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define apply8bitRangeLUT
def apply8bitRangeLUT(impA):
# for 8bit Gray scale image. Not support "RGB image" or "Stacked images"
if impA.getStackSize() > 1 or impA.getBitDepth() != 8:
IJ.showMessage("Not support [RGB image] or [Stacked images]")
raise RuntimeError("yamepi")
ip = impA.getProcessor()
displayMin = impA.getDisplayRangeMin()
displayMax = impA.getDisplayRangeMax()
# Changeing the display Range affect pixel values when saving.
# To prevent additional effects.
impA.resetDisplayRange()
lut = [0] * 256
for i in range(256):
if i <= displayMin:
lut[i] = 0
elif i >= displayMax:
lut[i] = 255
else:
lut[i] = int((float(i-displayMin) /(displayMax - displayMin)) * 256)
ip.applyTable(lut)
impA.setProcessor(ip)
return impA
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define extractOnlyRedChannel
def extractOnlyRedChannel(impA):
impMulti = ChannelSplitter.split(impA)
ipRed = impMulti[0].getProcessor()
impA.setProcessor(ipRed)
return impA
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define referenceCheck
def referenceCheck(dir):
global referLength
list = getFileList(dir)
if list[0].endswith("/"):
referenceCheck(dir + list[0])
else:
name = list[0]
dotIndex = name.rfind(".")
title = name[:dotIndex]
space = title.rfind(" ")
trueTitle = title[:space]
number = title[space+1:]
reference = trueTitle
referLength = len(reference)
IJ.log("Check trueTitle. (e.g. NARUTO_60)")
IJ.log("trueTitle=[" + trueTitle + "]")
logWindow.toFront()
IJ.showMessage("Check trueTitle (except : number.ext), and click [OK].")
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define getRoiNombre1
def getRoiNombre1():
while True:
waitForUser("ROI setting \n Open an image and set [ROI] using rectangle tool, then click [OK].")
nImages = WM.getImageCount()
if nImages != 1:
IJ.showMessage("Open only one image.")
continue
imp = IJ.getImage()
if imp.getRoi() is None:
continue
else:
break
IJ.run("Add to Manager") # Not use in this script.
imp = IJ.getImage()
# Add ROI position to memory
x1_nb, y1_nb, w1_nb, h1_nb = getBoundingRect(imp)
roi1_nb = Roi(x1_nb, y1_nb, w1_nb, h1_nb)
IJ.run("Close All") # close all "Images"
return roi1_nb
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define getRoiNombre2
def getRoiNombre2():
#ODD
while True:
waitForUser("ODD(1,3,5,7,...) \n Open an [ODD number] file and set [ROI] using rectangle tool, then click [OK].")
nImages = WM.getImageCount()
if nImages != 1:
IJ.showMessage("Open only one image.")
continue
imp = IJ.getImage()
if imp.getRoi() is None:
continue
else:
break
IJ.run("Add to Manager") # Not use in this script.
imp = IJ.getImage()
# Add ROI position to memory
x1_nb, y1_nb, w1_nb, h1_nb = getBoundingRect(imp)
roi1_nb = Roi(x1_nb, y1_nb, w1_nb, h1_nb)
IJ.run("Close All")
#EVEN
while True:
waitForUser("EVEN(2,4,6,8,...) \n Open an [EVEN number] file and set [ROI] using rectangle tool, then click [OK].")
nImages = WM.getImageCount()
if nImages != 1:
IJ.showMessage("Open only one image.")
continue
imp = IJ.getImage()
if imp.getRoi() is None:
continue
else:
break
IJ.run("Add to Manager") # Not use in this script.
imp = IJ.getImage()
# Add ROI position to memory
x2_nb, y2_nb, w2_nb, h2_nb = getBoundingRect(imp)
roi2_nb = Roi(x2_nb, y2_nb, w2_nb, h2_nb)
IJ.run("Close All")
return roi1_nb, roi2_nb
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define showMeOptMinAndMax3Trials
def showMeOptMinAndMax3Trials():
global flagExtactRedChannel
sumMin = 0
sumMax = 0
trials = 3
# create array
OPT_MAX = [0] * trials # [0,0,0,....0,0]
OPT_MIN = [0] * trials
# Enter Parameter
gd = GenericDialog("OptMinAndMax Setting")
gd.addNumericField("targetMeanWhite", 254.97)
gd.addNumericField("targetMeanBlack", 13)
gd.addCheckbox("Extract Red Channel", False)
gd.showDialog()
if gd.wasCanceled():
IJ.showMessage("Exit : Processing was canceled.")
raise RuntimeError("yamepi")
targetMeanWhite = float(gd.getNextNumber())
targetMeanBlack = float(gd.getNextNumber())
flagExtactRedChannel = gd.getNextBoolean()
if flagExtactRedChannel:
IJ.log("flagExtactRedChannel = ON")
# Define optimiseMinMax3Trials
def optimiseMinMax3Trials(now, trials, OPT_MIN, OPT_MAX):
IJ.log("")
IJ.log("optimiseMinAndMax")
nImages = WM.getImageCount()
if nImages == 0:
while True:
waitForUser("OptMinAndMax. Open an image, then click [OK]")
nImages = WM.getImageCount()
if nImages > 1:
IJ.showMessage("Open only one image.")
elif nImages == 1:
break
imp = IJ.getImage()
name = imp.getTitle()
if flagExtactRedChannel:
imp = extractOnlyRedChannel(imp)
# make tempDir and save original Image
tempDir = saveDir + "Temp_optMinMax/"
if not os.path.exists(tempDir):
os.makedirs(tempDir)
IJ.saveAs(imp, "PNG", tempDir + "CheckMaxAndMin.png")
# optimise max (white)
Toolbar.getInstance().setTool(Toolbar.RECTANGLE)
roi = Roi(10,10,100,100)
imp.setRoi(roi)
while True:
waitForUser("ROI selection, Set ROI on the [WHITE BACK GROUND], then click [OK].")
if imp.getRoi() is None:
continue
stats = imp.getStatistics() # histogram, area, mean, min, max, stdDev, mode
mean = stats.mean
area = stats.area
if mean < 150:
IJ.showMessage("Error!! This area is not WHITE BACK GROUND. Try Again")
else:
break
imp = cropRect(imp)
IJ.saveAs(imp, "PNG", tempDir + "CheckMax.png")
imp.changes = False
imp.close()
max = 254
min = 0
IJ.log("")
IJ.log("optimised Max Macro, TargetMean = " + str(targetMeanWhite))
for i in range(254):
imp = IJ.openImage(tempDir + "CheckMax.png")
ip = imp.getProcessor()
imp.setDisplayRange(min, max)
imp = apply8bitRangeLUT(imp)
stats = imp.getStatistics() # histogram, area, mean, min, max, stdDev, mode
mean = stats.mean
area = stats.area
IJ.log("Max = " + str(max) + ", mean = " + str(mean))
if mean >= targetMeanWhite:
optimisedMax = max
break
max = max - 1
imp.changes = False
imp.close()
IJ.log("optimisedMax = " + str(optimisedMax))
# optimise min (black)
imp = IJ.openImage(tempDir + "CheckMaxAndMin.png")
imp.show()
Toolbar.getInstance().setTool(Toolbar.RECTANGLE)
roi = Roi(10,10,100,100)
imp.setRoi(roi)
while True:
waitForUser("ROI selection, Set ROI on the [BLACK ZONE], then click [OK].")
if imp.getRoi() is None:
continue
stats = imp.getStatistics() # histogram, area, mean, min, max, stdDev, mode
mean = stats.mean
area = stats.area
if mean > 100:
IJ.showMessage("Error!! This area is not BLACK ZONE. Try Again")
else:
break
imp = cropRect(imp)
IJ.saveAs(imp, "PNG", tempDir + "CheckMin.png")
imp.changes = False
imp.close()
max = optimisedMax
min = 1
IJ.log("")
IJ.log("optimisedMin Macro, TargetMean = " + str(targetMeanBlack))
for i in range(254):
imp = IJ.openImage(tempDir + "CheckMin.png")
ip = imp.getProcessor()
imp.setDisplayRange(min, max)
imp = apply8bitRangeLUT(imp)
stats = imp.getStatistics() # histogram, area, mean, min, max, stdDev, mode
mean = stats.mean
area = stats.area
IJ.log("min = " + str(min) + ", mean = " + str(mean))
if mean <= targetMeanBlack:
optimisedMin = min
break
min = min + 1
imp.changes = False
imp.close()
# results
OPT_MIN[now] = optimisedMin
OPT_MAX[now] = optimisedMax
IJ.log("")
IJ.log(str(now + 1) + "/" + str(trials))
IJ.log("Title =" + name)
IJ.log("optimisedMin =" + str(optimisedMin))
IJ.log("optimisedMax =" + str(optimisedMax))
return OPT_MIN, OPT_MAX
# >>>>>>>> The End of optimiseMinMax3Trials
# trials and getting sum
for now in range(trials):
OPT_MIN, OPT_MAX = optimiseMinMax3Trials(now, trials, OPT_MIN, OPT_MAX)
sumMin += OPT_MIN[now]
sumMax += OPT_MAX[now]
# get average
min = int(sumMin / trials)
max = int(sumMax / trials)
IJ.log("")
time.sleep(1)
for i in range(trials):
IJ.log(str(i+1) + "..." + "min = " + str(OPT_MIN[i]) + ", max = " + str(OPT_MAX[i]))
IJ.log("")
IJ.beep()
time.sleep(1)
IJ.log("Result..." + "optMin = " + str(min) + ", optMax = " + str(max))
time.sleep(3)
IJ.log("")
return min, max
# showMeOptMinAndMax3Trials End
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define showMeOptMinAndMaxAuto
def showMeOptMinAndMaxAuto(dir):
global flagExtactRedChannel
gd = GenericDialog("Processing Setting")
gd.addNumericField("targetMeanWhite", 254.97, 2) #3rd argument is digit to right of decimal point
gd.addNumericField("targetMeanBlack", 13, 2) # default->18,27
gd.addMessage("")
gd.addNumericField("hoseiMax", -3)
gd.addNumericField("toBeCheckedFiles", 11)
gd.addMessage("")
gd.addCheckbox("Extract Red Channel", False)
gd.showDialog()
if gd.wasCanceled():
IJ.showMessage("Exit : Processing was canceled.")
raise RuntimeError("yamepi")
targetMeanWhite = gd.getNextNumber()
targetMeanBlack = gd.getNextNumber()
hoseiMax = gd.getNextNumber()
toBeCheckedFiles = int(gd.getNextNumber())
flagExtactRedChannel = gd.getNextBoolean()
if flagExtactRedChannel:
IJ.log("flagExtactRedChannel = ON")
# tempDir
tempDir = saveDir + "Temp_optMinMax/"
IJ.log("Temp dir :" + tempDir)
logWindow.toFront()
time.sleep(1)
# Make tempDir
if not os.path.exists(tempDir):
os.makedirs(tempDir)
# Create Array
extractStep = int(totalFiles / toBeCheckedFiles)
if extractStep <= 1:
IJ.showMessage("Error : extractStep <= 1. Mottto toBeCheckedFiles Sukunaku.")
raise RuntimeError("yamepi")
IJ.log("toBeCheckedFiles = " + str(toBeCheckedFiles) + ", extractStep = " + str(extractStep))
PATH_OMMA = []
#Define listFilesOMMA
def listFilesOMMA(dir, PATH_OMMA):
global seqPageNum, optAutoDetectCount
list = getFileList(dir)
for i in range(len(list)):
if list[i].endswith("/"):
PATH_OMMA= listFilesOMMA(dir + list[i], PATH_OMMA)
elif optAutoDetectCount < toBeCheckedFiles:
seqPageNum += 1
if seqPageNum % extractStep == 0:
PATH_OMMA = PATH_OMMA + [dir + list[i]]
optAutoDetectCount += 1
print "seqPageNum", seqPageNum
return PATH_OMMA
# >>>>>>>> The End of ListFilesOMMA
# Define optimiseMinMaxAuto
def optimiseMinMaxAuto():
optAutoCount = 0
OPT_MAX = []
OPT_MIN = []
for n in range(len(PATH_OMMA)):
imp = IJ.openImage(PATH_OMMA[n])
name = imp.getTitle()
# progress
IJ.log("")
IJ.log(str(optAutoCount + 1) + "/" + str(toBeCheckedFiles) + "... Progress = {:.2f}".format((float(optAutoCount + 1) / toBeCheckedFiles * 100)) + "%" + " [OptMinMaxAuto]")
IJ.log("..." + name)
IJ.log("")
if flagExtactRedChannel == 1:
imp = extractOnlyRedChannel(imp)
# resize for optAuto
width_org = imp.getWidth()
height_org = imp.getHeight()
height_re = height_org * 1400 / width_org
imp = imp.resize(1400, height_re, "bicubic")
imp.show()
time.sleep(1)
ip = imp.getProcessor()
depth = imp.getBitDepth()
if depth == 8:
width = imp.getWidth()
height = imp.getHeight()
x = 0
y = 0
sum = 0
whiteCheckCount = 0
blackCheckCount = 0
whiteSegCount = 0
blackSegCount = 0
whiteMax = 0
blackMin = 255
# whiteBackGround
segCount = 0
xSeg = 50
ySeg = 50
xStep = xSeg
yStep = ySeg
xSeg_white = xSeg
ySeg_white = ySeg
for x in range(0, width - xSeg, xStep):
for xi in range(xSeg):
for yi in range(ySeg):
pixelValue = ip.getPixel(x + xi, y + yi)
sum = sum + pixelValue
mean = float(sum) / xSeg / ySeg
IJ.log("\\Update:White... count = "+str(segCount) + ", x = " + str(x) + ", y = " + str(y) + ", mean = " + str(mean) )
if mean > whiteMax:
whiteMax = mean
whiteSegCount = segCount
x_white = x
y_white = y
whiteCheckCount += 1
sum = 0
segCount += 1
# blackKuroBeta
segCount = 0
xSeg = 40
ySeg = 40
xStep = xSeg
yStep = ySeg
xSeg_black = xSeg
ySeg_black = ySeg
for y in range(0, height - ySeg, yStep):
for x in range(0, width - xSeg, xStep):
for xi in range(xSeg):
for yi in range(ySeg):
pixelValue = ip.getPixel(x + xi, y + yi)
sum = sum + pixelValue
mean = float(sum) / xSeg / ySeg
IJ.log("\\Update:Black... count = "+str(segCount) + ", x = " + str(x) + ", y = " + str(y) + ", mean = " + str(mean) )
if mean < blackMin:
blackMin = mean
blackSegCount = segCount
x_black = x
y_black = y
blackCheckCount += 1
sum = 0
segCount += 1
imp.changes = False
imp.close()
# create cropped images of most white and most black
imp = IJ.openImage(PATH_OMMA[n])
imp = imp.resize(1400, height_re, "bicubic")
Toolbar.getInstance().setTool(Toolbar.RECTANGLE)
roi = Roi(x_white, y_white, xSeg_white, ySeg_white)
imp.setRoi(roi)
imp = cropRect(imp)
if flagExtactRedChannel == 1:
imp = extractOnlyRedChannel(imp)
saveTitle = "wSegNo" + zeroPad(whiteSegCount, 6) + ".png"
IJ.saveAs(imp, "PNG", tempDir + saveTitle)
imp.changes = False
imp.close()
imp = IJ.openImage(PATH_OMMA[n])
imp = imp.resize(1400, height_re, "bicubic")
Toolbar.getInstance().setTool(Toolbar.RECTANGLE)
roi = Roi(x_black, y_black, xSeg_black, ySeg_black)
imp.setRoi(roi)
imp = cropRect(imp)
if flagExtactRedChannel == 1:
imp = extractOnlyRedChannel(imp)
saveTitle = "bSegNo" + zeroPad(blackSegCount, 6) + ".png"
IJ.saveAs(imp, "PNG", tempDir + saveTitle)
imp.changes = False
imp.close()
# checkMax Loop
optimisedMax = 0 # If not found
max = 254
min = 0
IJ.log("Checking Max..." + "wSegNo" + zeroPad(whiteSegCount,6) + ".png")
for i in range(254):
imp = IJ.openImage(tempDir + "wSegNo" + zeroPad(whiteSegCount, 6) + ".png")
ip = imp.getProcessor()
imp.setDisplayRange(min, max)
imp = apply8bitRangeLUT(imp)
stats = imp.getStatistics() # histogram, area, mean, min, max, stdDev, mode
mean = stats.mean
area = stats.area
if mean >= targetMeanWhite:
optimisedMax = max
break
max = max - 1
imp.changes = False
imp.close()
IJ.log("Temp_optimisedMax = " + str(optimisedMax))
OPT_MAX = OPT_MAX + [optimisedMax]
# checkMin Loop
optimisedMin = 255 # If not found
max = 220 # Daitai 200 Gurai Ooi kara
min = 1
IJ.log("Checking Min..." + "bSegNo" + zeroPad(blackSegCount, 6) + ".png")
for i in range(254):
imp = IJ.openImage(tempDir + "bSegNo" + zeroPad(blackSegCount, 6) + ".png")
ip = imp.getProcessor()
imp.setDisplayRange(min, max)
imp = apply8bitRangeLUT(imp)
stats = imp.getStatistics() # histogram, area, mean, min, max, stdDev, mode
mean = stats.mean
area = stats.area
if mean <= targetMeanBlack:
optimisedMin = min
break
min = min + 1
if min == max:
break
imp.changes = False
imp.close()
IJ.log("Temp_optimisedMin = " + str(optimisedMin))
OPT_MIN = OPT_MIN + [optimisedMin]
else: # else if(depth != 8bit)
imp.changes = False # original Image
imp.close()
OPT_MAX = OPT_MAX + [0]
OPT_MIN = OPT_MIN + [255]
IJ.log("detect color image")
IJ.log("Temp_optimisedMax = 0")
IJ.log("Temp_optimisedMin = 255")
optAutoCount += 1
return OPT_MIN, OPT_MAX
# >>>>>>>> The End of optimiseMinAndAuto
# Define optmiseMinMaxResults
def optimiseMinMaxResults(OPT_MIN, OPT_MAX):
# Max
# Outlier Exclusion (OPT_MAX[i] > 150)
OPT_MAX = [x for x in OPT_MAX if x > 150]
OPT_MAX.sort()
acceptCountMax = len(OPT_MAX)
if acceptCountMax == 0:
IJ.showMessage("Error! extractStep motto sukunaku.")
raise RuntimeError("yamepi")
median = int(acceptCountMax / 2)
if acceptCountMax % 2 == 0:
median = median - 1
optimisedMax = OPT_MAX[median] + hoseiMax
# Min
# Outlier Exclusion (OPT_MIN[i] < 100)
OPT_MIN = [x for x in OPT_MIN if x < 100]
OPT_MIN.sort()
acceptCountMin = len(OPT_MIN)
if acceptCountMin == 0:
IJ.showMessage("Error! extractStep motto sukunaku.")
raise RuntimeError("yamepi")
median = int(acceptCountMin / 2)
if acceptCountMin % 2 == 0:
median = median - 1
optimisedMin = OPT_MIN[median]
# Result
IJ.log("")
IJ.log("OPT_MAX = " + str(OPT_MAX))
IJ.log("OPT_MIN = " + str(OPT_MIN))
IJ.log("")
time.sleep(1)
IJ.log("acceptCount... (min, max) = (" + str(acceptCountMin) + ", " + str(acceptCountMax) + ")")
IJ.log("Correction to max... " + str(hoseiMax))
IJ.log("")
IJ.beep()
time.sleep(1)
IJ.log("Result...")
IJ.log("optMin = " + str(optimisedMin) + ", optMax = " + str(optimisedMax))
time.sleep(3)
IJ.log("")
return optimisedMin, optimisedMax
# >>>>>>>> The End of optimiseMinAndAutoResults
PATH_OMMA= listFilesOMMA(openDir, PATH_OMMA)
IJ.log("")
IJ.log("Check for...")
for i in range(len(PATH_OMMA)):
IJ.log(PATH_OMMA[i])
IJ.log("")
OPT_MIN, OPT_MAX = optimiseMinMaxAuto()
optimisedMin, optimisedMax = optimiseMinMaxResults(OPT_MIN, OPT_MAX)
min = optimisedMin
max = optimisedMax
return min, max
# showMeOptMinAndMaxAuto end
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define showMeOptMinAndMaxMokushiNow
def showMeOptMinAndMaxMokushiNow():
global flagExtactRedChannel
gd = GenericDialog("Processing Setting")
items = ["Use Interactive UI", "Use Normal B&C Window"]
gd.addRadioButtonGroup("Select Proc Type", items, 2, 1, "Use Interactive UI")
gd.addCheckbox("Extract Red Channel", False)
gd.showDialog()
if gd.wasCanceled():
IJ.showMessage("Exit : Processing was canceled.")
raise RuntimeError("yamepi")
mokushiRadio = gd.getNextRadioButton()
flagExtactRedChannel = gd.getNextBoolean()
if mokushiRadio == "Use Interactive UI":
mokushiType = 1
elif mokushiRadio == "Use Normal B&C Window":
mokushiType = 2
if flagExtactRedChannel:
IJ.log("flagExtactRedChannel = ON")
while True:
if mokushiRadio == "Use Interactive UI":
waitForUser("Open an image, and Please [Zoom In] the image \nto make it easier to see. \nThen click [OK]")
elif mokushiRadio == "Use Normal B&C Window":
waitForUser("Open an image. Then click [OK]")
nImages = WM.getImageCount()
if nImages > 1:
IJ.showMessage("Open only one image.")
elif nImages == 1:
break
imp = IJ.getImage()
# Define contrrAdjustUI
class ContrAdjustPreviewer(AdjustmentListener, ItemListener):
def __init__(self, imp, sliderMin, sliderMax):
self.imp = imp
self.ip = imp.getProcessor()
self.original_ip = imp.getProcessor().duplicate() # store original Image
self.sliderMin = sliderMin
self.sliderMax = sliderMax
def adjustmentValueChanged(self, event):
# If the change in the Slider's Value has been detected...
self.contrAdjust()
def reset(self):
#restore original Image
self.imp.setProcessor(self.original_ip)
def contrAdjust(self):
global minMokushi, maxMokushi
# SetMinAndMax...main method
minMokushi = self.sliderMin.getValue()
maxMokushi = self.sliderMax.getValue()
self.ip.setMinAndMax(minMokushi,maxMokushi)
print minMokushi,maxMokushi
self.imp.setProcessor(self.ip)
def contrrAdjustUI(imp):
gd = GenericDialog("Set Min And Max")
gd.addSlider("min", 0, 255, 0)
gd.addSlider("max", 0, 255, 255)
sliderMin = gd.getSliders().get(0)
sliderMax = gd.getSliders().get(1)
imp = WM.getCurrentImage()
depth = imp.getBitDepth()
if depth == 24:
imp = extractOnlyRedChannel(imp)
previewer = ContrAdjustPreviewer(imp, sliderMin, sliderMax)
sliderMin.addAdjustmentListener(previewer)
sliderMax.addAdjustmentListener(previewer)
gd.showDialog()
if gd.wasCanceled():
previewer.reset()
print "Reset Image"
IJ.showMessage("Exit : Processing was canceled.")
raise RuntimeError("yamepi")
else:
previewer.contrAdjust()
# >>>>>>>> The End of contrrAdjustUI
def conventionalUI(imp):
global minMokushi, maxMokushi
IJ.run("Brightness/Contrast...")
depth = imp.getBitDepth()
if depth == 24:
imp = extractOnlyRedChannel(imp)
waitForUser("Adjust min and max with B&C Slider, then click [OK]. \n(Don't click [Apply]!)")
minMokushi = imp.getDisplayRangeMin()
maxMokushi = imp.getDisplayRangeMax()
print minMokushi, maxMokushi
# >>>>>>>> The End of conventionalUI
# Obtain optimised min,max by mokushi
if mokushiType == 1:
contrrAdjustUI(imp)
elif mokushiType == 2:
conventionalUI(imp)
# Results
min = minMokushi
max = maxMokushi
imp.changes = False
imp.close()
IJ.log("")
time.sleep(1)
IJ.log("min = " + str(min) + ", max = " + str(max))
time.sleep(3)
IJ.log("")
return min, max
# showMeOptMinAndMaxMokushiNow End
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
def convKernel(ip):
kernel = [-1, -1, -1, -1, 12, -1, -1,-1,-1]
Convolver().convolve(ip, kernel, 3,3)
imp_new = ImagePlus("Filterd Image", ip)
return imp_new
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#Define shapeningFilter
def shapeningFilter(impA):
if impA.getStackSize() > 1 :
IJ.showMessage("Not support [Stacked images]")
raise RuntimeError("yamepi")
elif impA.getBitDepth() == 8:
ip = impA.getProcessor()
impFiltered = convKernel(ip)
return impFiltered
elif impA.getBitDepth() == 24:
# Split to R,G,B imp
impMulti = ChannelSplitter.split(impA)
impRed = impMulti[0]
impGreen = impMulti[1]
impBlue = impMulti[2]
# Convolve R, G, B channels with a sharpening filter.
ipRed = impRed.getProcessor()
ipGreen = impGreen.getProcessor()
ipBlue = impBlue.getProcessor()
impRed = convKernel(ipRed)
impGreen = convKernel(ipGreen)
impBlue = convKernel(ipBlue)
# Get pixel arrays
redPixelsArray = impRed.getProcessor().getPixels()
greenPixelsArray = impGreen.getProcessor().getPixels()
bluePixelsArray = impBlue.getProcessor().getPixels()
# Create new ImageProcessor (ColorProcessor)
width = impRed.width
height = impRed.height
rgbProcessor = ColorProcessor(width, height)
# Set pixel values
rgbProcessor.setRGB(redPixelsArray, greenPixelsArray, bluePixelsArray)
# Convert to RGB image
impFilteredMerged = ImagePlus("Filterd RGB Image", rgbProcessor)
return impFilteredMerged
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define mainOpe
def mainOpe(filepath):
global procCount, trueTitle, numberOfPage, previousTitle
procCount += 1
# Progress display
IJ.log(str(procCount) + "/" + str(totalFiles) + "... Progress = {:.2f}".format(float(procCount) / totalFiles * 100) + "%")
imp = IJ.openImage(filepath)
ip = imp.getProcessor()
# Rename Section
if not flagRenumATMT: # Normal
name = imp.getTitle()
dotIndex = name.rfind(".")
title = name[:dotIndex]
underBar = title.rfind("_")
trueTitle = title[:underBar]
number = title[underBar+1:]
newname = title + ext
if flagAddSuffix:
trueTitle = trueTitle + "_" + suffix
newname = trueTitle + "_" + number + ext
if flagRenumFrom1:
if not trueTitle == previousTitle:
numberOfPage = 1
previousTitle = trueTitle
newname = trueTitle + "_" + zeroPad(numberOfPage, digit) + ext
numberOfPage += 1
# Output Correspondence table
rt.incrementCounter() # Adds a row
rt.addValue("", procCount)
rt.addValue("Original", name)
rt.addValue("New name", newname)
elif flagRenumATMT:
name = imp.getTitle()
dotIndex = name.rfind(".")
title = name[:dotIndex]
# ReNumbering
titleLength = len(title)
if referLength < titleLength:
space = title.rfind(" ")
trueTitle = title[:space]
number = title[space+1:]
newname = trueTitle + "_" + zeroPad(number, digit) + ext
elif referLength == titleLength:
newname = title + "_" + zeroPad(1, digit) + ext
dotIndex = newname.rfind(".")
title = newname[:dotIndex]
underBar = title.rfind("_")
trueTitle = title[:underBar]
number = title[underBar+1:]
# Nombre Cut
if flagNombre:
if NombreType == 1:
imp.setRoi(roi1_nb)
imp = cropRect(imp)
if NombreType == 2:
number = int(number)
if number == 0:
IJ.showMessage("Error!! Number must not be null.")
raise RuntimeError("yamepi")
# ODD(1,3,5,7,...)
if number % 2 == 1:
imp.setRoi(roi1_nb)
imp = cropRect(imp)
# EVEN(2,4,6,8,...)
if number % 2 == 0:
imp.setRoi(roi2_nb)
imp = cropRect(imp)
# Filtering
if flagSharpen:
imp = shapeningFilter(imp)
# SetResolution
if flagReso:
width = int(imp.getWidth() * compressionRate)
height = int(imp.getHeight() * compressionRate)
imp = imp.resize(width, height, "bicubic")
ip = imp.getProcessor()
# ContrastAdjust 8 bit
depth = imp.getBitDepth()
if not (flagFullColor or flagExtactRedChannel):
if depth == 8:
# ContrastAdjust
if flagContr:
imp.setDisplayRange(min, max)
imp = apply8bitRangeLUT(imp)
if flagFullColor:
# ContrastAdjust
if flagContr:
imp.setDisplayRange(min, max)
IJ.run(imp, "Apply LUT", "")
if flagExtactRedChannel:
# extract red channel to suppress yellowing
imp = extractOnlyRedChannel(imp)
ip = imp.getProcessor()
# ContrastAdjust
if flagContr:
imp.setDisplayRange(min, max)
imp = apply8bitRangeLUT(imp)
# Save to SubDirectory
subDir = parentDir + trueTitle + "/"
if not os.path.exists(subDir):
os.makedirs(subDir)
if not (flagContr or flagReso or flagNombre or flagSharpen):
if flagRenumFrom1 or flagRenumATMT:
shutil.copy2(filepath, subDir + newname)
IJ.log("Copy to..." + subDir + newname)
elif ext == ".jpg":
IJ.saveAs(imp, "JPEG", subDir + newname)
IJ.log("Save to..." + subDir + newname)
elif ext == ".png":
IJ.saveAs(imp, "PNG", subDir + newname)
IJ.log("Save to..." + subDir + newname)
IJ.run("Close All")
# mainOpe End
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Define GenerateImg
def GenerateImg():
w = 108
h = 127
img = [
[234,213,214,208,211,226,216,199,220,166,75,98,187,90,63,67,62,67,60,69,70,56,68,79,78,80,87,74,89,86,86,94,96,104,96,97,181,169,171,176,129,103,214,255,238,237,232,249,241,246,237,234,237,226,205,185,181,190,198,200,190,189,184,199,200,207,194,192,197,227,248,246,234,232,240,252,244,241,231,237,249,250,242,229,234,241,246,240,230,228,238,249,248,237,230,235,247,251,242,230,230,245,253,241,234,229,238,248,],
[228,212,221,219,209,206,223,214,220,182,103,122,180,150,149,105,108,143,129,126,137,131,120,108,110,120,124,119,130,135,130,132,130,123,143,150,208,183,172,169,162,152,209,232,244,229,240,245,234,242,247,250,234,196,146,100,87,95,91,87,68,61,66,96,98,94,84,90,107,164,214,246,251,247,237,233,235,248,247,242,236,233,242,247,247,241,237,241,249,251,244,236,241,244,245,242,237,236,240,245,242,241,237,240,246,245,248,247,],
[233,215,219,214,213,217,207,205,211,212,215,212,208,146,157,170,218,172,177,195,169,174,176,175,175,179,174,167,175,172,171,180,183,183,175,174,194,180,165,183,173,184,186,194,200,196,248,232,222,235,254,251,236,207,163,103,93,117,105,88,56,33,60,126,130,84,70,98,161,203,225,246,250,249,237,230,230,250,254,244,230,225,241,255,243,231,223,233,250,254,239,221,227,244,255,249,231,225,241,255,255,235,216,232,250,255,255,251,],
[230,210,211,203,214,223,214,213,222,220,213,205,217,106,100,165,145,58,78,74,79,68,77,91,80,88,100,101,102,98,112,107,93,115,98,124,113,119,106,154,198,195,179,181,112,172,247,230,246,248,243,245,250,250,220,137,118,156,139,106,61,40,79,163,171,110,88,126,204,240,240,250,249,250,240,234,235,246,245,243,239,235,241,246,243,239,238,241,248,249,245,240,236,241,245,244,240,238,241,245,248,239,228,244,243,240,249,251,],
[234,217,220,215,206,208,211,206,222,222,197,211,220,101,65,161,151,149,115,79,102,110,102,107,107,95,82,101,96,91,107,103,106,116,103,108,98,115,128,158,203,155,149,162,101,179,231,240,253,248,228,229,240,255,235,140,111,153,133,98,56,45,80,168,178,126,95,131,217,253,241,238,229,236,242,251,240,237,228,236,248,245,238,228,237,244,249,244,233,231,241,252,252,238,228,234,250,254,242,226,231,246,250,255,234,222,238,247,],
[230,212,216,212,209,226,216,208,217,215,209,210,216,219,214,207,155,170,135,220,193,196,194,198,186,183,177,182,175,181,188,173,190,166,193,179,200,175,188,201,204,176,186,198,193,203,204,227,192,211,232,227,234,247,235,145,115,152,129,98,58,45,74,176,183,129,86,128,207,255,249,246,228,230,241,255,248,238,226,238,255,253,240,225,237,249,255,245,227,222,237,254,251,234,222,229,247,254,243,227,227,247,250,255,229,223,241,244,],
[230,216,217,210,212,217,217,209,216,221,215,217,214,215,212,222,139,119,111,194,104,81,89,91,86,99,94,94,112,104,102,109,116,115,115,117,126,114,113,122,127,133,136,169,175,192,178,132,145,208,255,246,254,239,225,140,122,155,151,101,66,37,75,180,178,128,94,141,211,244,251,248,238,248,235,242,244,244,244,243,240,239,239,240,243,242,242,243,244,243,242,243,242,240,241,246,245,239,239,245,243,242,237,241,247,242,242,254,],
[229,214,215,209,211,216,214,208,210,216,207,209,222,217,209,215,170,77,109,163,140,115,87,77,76,83,91,97,87,79,76,82,87,88,90,95,90,101,103,106,107,102,120,198,185,145,174,121,133,200,251,250,242,224,213,144,133,164,147,104,70,51,84,171,159,114,97,147,220,233,227,236,248,255,236,227,236,248,255,245,231,229,241,255,251,234,223,234,252,255,242,228,229,246,255,246,228,225,239,255,251,241,227,230,247,252,247,248,],
[229,215,216,210,211,218,213,211,211,220,208,212,213,213,218,220,193,195,185,190,166,157,160,150,175,155,174,180,99,92,87,88,89,89,92,96,104,102,106,111,101,99,135,222,130,93,177,124,147,215,252,254,239,228,206,136,125,166,145,108,64,44,71,160,162,119,102,138,226,236,223,233,251,251,237,222,235,248,254,245,231,230,242,253,251,234,224,235,252,253,241,228,232,246,255,244,229,227,241,255,251,240,227,232,248,249,246,251,],
[230,216,217,211,211,219,213,215,212,225,210,214,218,199,202,231,219,207,221,201,138,118,159,98,138,134,154,157,84,82,82,85,88,91,95,100,94,100,94,97,109,108,123,199,172,152,178,104,131,206,238,236,246,233,186,126,111,144,133,110,83,82,115,184,175,126,104,120,204,243,246,243,242,236,247,246,244,239,237,240,245,245,238,232,237,242,247,244,236,233,238,246,249,236,231,239,248,247,241,238,237,239,242,247,243,229,234,255,],
[228,214,216,210,210,218,211,212,209,221,204,208,225,220,211,218,214,215,219,189,90,81,47,101,79,71,81,86,85,88,92,97,99,101,104,106,104,96,111,119,105,112,119,138,105,123,119,117,155,221,243,213,238,204,138,113,106,116,116,112,126,111,115,145,149,133,125,129,152,221,247,237,223,219,245,255,250,233,225,239,255,253,237,223,228,247,255,245,225,223,239,255,254,232,220,234,255,255,240,224,228,243,253,251,236,220,229,255,],
[229,215,217,211,209,216,212,211,212,221,206,208,222,213,200,200,240,197,219,213,182,162,173,166,170,172,186,178,172,176,179,179,178,177,176,176,181,184,185,181,180,186,170,176,186,195,166,185,161,198,250,234,232,186,111,88,88,94,90,79,91,80,107,135,126,92,83,104,147,213,244,245,237,238,247,251,244,236,233,242,248,245,239,237,238,244,245,239,234,238,244,246,244,241,238,238,242,246,241,233,236,248,248,240,237,235,238,249,],
[230,217,219,213,211,216,215,212,217,223,211,210,226,207,215,216,216,209,194,237,222,216,227,215,218,207,219,213,212,215,216,215,215,217,218,217,221,212,214,215,212,227,219,219,206,212,211,224,167,195,255,254,238,198,142,104,104,123,105,80,72,49,89,127,136,103,84,105,159,196,217,240,249,253,235,232,235,244,249,244,234,233,242,253,248,237,231,238,250,252,243,233,233,246,253,246,234,231,240,249,250,244,233,233,247,251,248,249,],
[229,216,218,212,213,217,217,209,216,218,207,205,230,207,208,215,216,207,226,218,201,222,198,221,207,219,209,207,215,215,212,206,204,207,208,208,207,213,211,208,210,211,198,219,211,208,220,206,168,213,249,236,182,152,136,113,124,151,128,110,94,80,122,137,146,129,106,115,159,172,187,229,253,255,227,225,231,250,255,243,225,227,244,255,247,230,225,242,255,251,236,226,230,240,251,250,235,225,237,255,255,233,218,233,254,252,246,254,],
[193,172,228,203,215,217,217,216,209,222,202,210,220,210,205,222,218,208,204,224,207,210,213,213,202,211,214,216,207,207,205,203,212,216,207,210,208,210,207,213,207,209,206,211,208,214,203,215,168,201,255,225,198,185,125,123,159,174,127,112,89,66,84,154,162,132,99,124,163,187,202,232,243,242,238,242,243,240,240,243,242,238,239,245,246,240,237,239,240,240,241,244,248,237,244,239,235,243,242,241,239,242,240,243,242,236,243,253,],
[253,205,220,208,210,219,213,204,210,225,204,211,222,207,210,214,225,207,214,227,205,207,206,220,166,173,198,192,173,213,208,209,210,209,205,211,212,213,211,216,211,213,210,214,209,212,208,212,172,206,240,223,245,233,175,155,189,207,156,127,83,55,88,181,200,140,127,130,186,237,252,246,227,229,244,255,243,232,228,239,253,253,239,225,236,247,252,243,230,228,242,255,249,232,232,240,248,254,244,231,232,244,252,247,236,229,236,253,],
[244,245,220,225,208,213,221,211,207,223,213,203,225,208,211,210,223,207,215,222,210,214,205,210,131,143,149,142,130,217,214,211,207,208,211,210,209,210,208,212,208,209,207,210,210,209,212,210,174,211,230,229,245,231,182,152,195,226,179,138,88,48,91,192,215,154,145,137,196,251,255,241,223,230,245,251,243,233,228,239,255,255,241,224,233,248,255,244,229,229,242,255,248,235,229,243,254,253,245,228,234,243,255,246,234,231,233,254,],
[249,217,183,145,183,210,219,208,221,224,208,213,227,212,207,214,217,212,213,217,212,216,206,206,175,199,142,125,153,216,210,209,212,210,213,209,211,210,209,210,209,210,210,212,210,206,212,211,171,210,239,244,243,219,175,146,200,233,191,145,86,39,89,189,215,186,163,162,197,235,232,239,245,246,242,235,238,243,246,242,238,239,243,246,241,240,238,239,243,246,241,234,241,245,241,245,241,235,241,237,250,238,242,237,241,246,239,255,],
[245,248,228,217,195,198,210,210,207,210,206,197,225,211,208,218,217,215,216,219,206,216,212,203,196,220,193,211,212,210,205,208,218,207,210,209,211,209,208,206,208,209,212,212,213,207,210,215,165,205,255,255,243,213,170,152,213,237,196,153,79,36,86,189,224,194,166,166,197,229,224,244,255,248,235,224,234,249,255,245,227,225,241,255,249,234,225,236,254,255,240,223,232,251,252,245,229,222,239,248,255,232,228,232,249,255,244,254,],
[236,251,255,239,246,243,218,212,226,226,211,216,225,208,211,217,218,210,216,217,214,207,201,212,216,213,216,212,216,202,218,210,212,208,214,210,209,208,208,204,208,208,211,210,215,210,207,217,165,201,255,252,237,213,167,159,220,236,197,156,82,42,86,197,234,178,169,163,195,238,230,241,250,244,240,232,237,245,251,247,237,233,240,249,247,236,232,240,249,248,239,233,234,249,251,244,236,233,242,251,251,233,231,237,249,250,241,252,],
[235,236,237,240,234,212,180,183,192,210,208,205,224,208,209,221,213,207,212,217,223,213,212,216,208,193,215,203,206,203,222,211,207,211,217,211,213,212,214,209,214,212,214,210,213,212,205,214,171,205,249,234,246,237,181,169,224,235,201,160,80,41,92,206,227,180,182,177,193,252,244,240,239,239,250,251,242,236,235,243,250,248,240,233,237,242,247,244,237,234,240,248,246,240,237,239,250,249,240,244,235,240,245,244,239,234,238,252,],
[208,141,117,206,227,213,174,178,192,216,212,217,221,209,203,230,206,214,212,225,203,201,216,211,216,215,218,201,236,213,206,210,212,210,209,211,210,209,213,208,214,209,211,205,210,211,204,210,178,211,235,219,239,245,181,164,215,232,206,166,72,33,99,208,201,184,170,167,188,255,253,240,225,219,242,255,243,228,222,236,252,252,238,224,229,246,255,246,230,228,240,253,255,231,221,231,255,255,232,232,225,248,255,247,230,222,237,253,],
[154,61,82,112,136,187,212,230,243,221,213,209,233,202,204,224,220,211,213,223,213,206,215,198,196,197,205,198,199,208,202,207,197,209,206,202,203,207,199,199,209,199,206,206,195,218,223,200,170,206,248,228,249,227,188,170,213,247,211,166,79,35,98,200,215,175,174,164,205,245,238,255,221,232,250,243,244,243,243,242,240,240,238,240,243,243,243,240,237,240,240,246,246,244,233,239,243,247,240,239,241,240,246,247,231,241,238,253,],
[171,62,92,65,76,88,126,153,172,205,181,201,212,220,211,206,219,205,219,213,210,215,201,159,193,176,171,181,178,160,177,171,182,162,173,175,168,178,178,176,178,169,177,170,150,198,207,207,171,202,254,250,247,214,168,165,215,234,192,157,77,43,98,203,212,183,174,167,181,239,233,227,255,255,233,229,233,253,246,233,251,234,242,240,231,241,229,243,254,253,229,232,225,247,255,242,224,238,233,244,252,245,231,230,242,249,255,245,],
[201,130,97,99,87,79,85,90,144,126,147,155,203,213,220,214,226,200,217,217,216,211,207,160,175,174,189,181,170,199,178,181,175,183,190,190,174,185,185,177,179,184,187,152,119,198,211,218,171,197,251,252,244,201,144,149,197,192,144,121,72,46,88,191,183,152,141,155,194,226,198,175,222,202,240,221,236,246,244,248,213,228,251,255,255,219,229,224,248,250,248,221,233,248,237,255,239,217,241,255,255,240,219,231,254,251,240,252,],
[193,162,173,134,112,93,80,75,92,107,129,184,244,208,214,220,223,213,213,214,211,211,198,167,190,211,210,194,216,201,206,203,154,179,152,193,214,209,209,208,208,213,212,166,100,197,218,214,171,204,248,243,239,199,133,136,179,158,110,94,51,47,76,148,146,136,104,76,81,113,113,87,34,54,80,94,143,85,157,150,234,225,231,250,229,236,248,247,242,242,238,240,243,245,237,243,237,238,243,243,236,238,238,248,242,226,175,242,],
[235,175,138,163,144,122,96,101,70,101,105,123,204,197,199,219,210,212,212,222,222,204,185,166,191,199,204,213,220,205,216,179,169,140,116,183,221,204,208,220,213,203,205,168,103,191,218,203,172,208,239,230,239,207,134,136,181,160,115,95,60,50,78,132,108,65,41,35,25,14,24,62,52,56,33,62,57,61,72,60,111,148,169,143,214,255,239,251,229,221,254,250,252,243,224,234,244,255,245,216,226,255,255,214,161,133,100,229,],
[210,158,82,90,116,121,112,65,88,89,90,114,136,142,105,168,218,218,213,211,210,217,208,156,192,214,227,211,195,233,211,190,188,170,166,198,219,208,214,219,213,212,213,167,120,193,219,206,175,207,233,229,243,211,133,139,188,167,122,92,63,56,89,137,133,108,98,85,97,94,79,43,59,50,77,84,135,86,92,94,61,73,63,104,141,177,246,251,228,230,243,249,254,237,213,249,254,242,250,235,234,235,193,146,116,96,97,239,],
[162,38,64,59,73,97,120,127,102,52,90,65,91,78,36,119,214,197,212,221,207,213,193,155,207,190,174,186,194,176,188,203,160,188,179,187,185,182,185,183,179,190,196,146,112,195,216,213,172,209,246,248,238,204,127,144,191,162,119,86,52,45,96,167,163,129,125,128,166,185,195,152,120,92,71,71,88,140,155,143,110,102,71,82,75,124,132,189,226,241,242,239,235,235,254,250,230,241,237,244,201,151,106,107,121,136,125,241,],
[194,96,93,57,53,64,106,143,162,99,71,64,58,24,19,111,230,210,226,221,207,220,198,118,87,89,101,99,108,80,94,89,102,96,95,99,99,89,97,102,92,90,109,86,99,200,215,216,160,203,253,253,226,192,124,151,196,160,121,95,58,47,81,141,142,134,132,119,158,221,230,233,223,155,109,69,42,68,80,131,161,141,129,85,107,69,86,101,170,221,225,233,235,247,251,246,232,240,225,190,144,104,95,91,67,113,101,233,],
[211,141,119,105,53,58,38,90,141,128,107,52,35,53,19,64,120,126,136,207,204,205,225,184,200,195,176,190,190,189,202,177,199,185,182,192,191,190,196,190,189,194,195,193,192,215,213,212,158,206,251,246,249,186,129,156,187,166,130,99,52,44,75,143,136,129,133,128,151,217,227,253,239,218,177,131,93,87,93,89,106,166,156,167,110,99,81,98,94,149,205,219,235,247,254,251,244,200,149,109,86,76,83,106,102,110,73,230,],
[202,70,66,74,93,35,33,23,49,58,46,26,67,27,41,61,72,68,86,190,224,210,218,206,219,202,224,225,203,214,207,215,208,213,230,203,211,217,202,214,222,198,203,221,213,214,202,211,174,210,244,236,247,197,133,148,196,169,125,98,53,42,79,139,133,132,125,121,180,232,254,231,168,172,101,82,52,95,42,53,56,50,120,144,132,115,100,96,96,98,128,207,238,241,222,239,214,109,54,49,86,108,146,126,99,107,130,229,],
[195,101,98,99,80,39,38,30,9,34,21,43,6,75,110,173,116,52,72,202,225,210,212,219,214,218,209,213,218,221,214,222,208,214,214,211,214,210,217,211,212,225,213,208,200,210,213,218,182,201,229,225,243,203,133,143,203,172,123,99,58,43,82,136,131,132,115,113,171,222,254,222,171,118,135,149,173,168,139,89,71,56,52,75,117,105,105,96,73,101,92,140,193,224,242,150,81,35,63,89,126,147,98,113,130,155,201,253,],
[183,95,88,100,81,54,73,25,23,6,51,121,100,87,151,144,169,81,73,160,133,140,152,130,146,153,147,154,149,133,155,163,161,157,157,168,162,138,163,163,150,162,149,162,166,163,149,147,155,208,250,245,238,194,127,149,201,173,129,101,52,38,74,132,131,129,118,121,171,225,253,248,233,226,231,253,251,253,216,166,118,85,78,47,98,106,116,98,87,69,82,127,123,136,141,83,42,99,124,148,111,99,121,169,220,237,242,255,],
[203,121,145,144,95,96,57,3,31,19,137,158,79,90,118,115,92,80,100,75,71,81,38,43,50,92,98,95,101,115,111,124,197,230,235,225,215,222,221,231,231,228,211,209,220,239,237,216,200,225,254,255,239,181,118,158,195,172,137,101,53,43,68,133,131,120,119,125,163,225,224,238,255,254,240,230,235,254,246,223,167,122,104,76,27,81,105,154,107,64,71,73,64,48,30,67,102,123,107,117,122,144,183,214,241,253,241,253,],
[224,255,253,234,213,199,106,92,49,55,121,121,98,105,71,84,96,104,79,68,65,65,73,57,33,51,93,118,121,153,134,103,145,230,251,231,204,188,193,221,224,231,226,238,239,248,243,236,231,242,248,252,244,178,112,153,193,168,138,98,52,47,69,136,136,121,122,128,159,229,224,243,227,214,155,145,139,154,135,142,119,77,81,90,99,24,73,123,139,112,60,39,34,15,49,83,121,99,98,126,184,243,221,246,252,255,245,254,],
[255,245,221,193,155,86,73,112,114,129,101,121,95,84,92,87,71,100,96,74,75,53,73,72,29,42,34,69,94,131,177,167,115,168,199,161,124,107,119,124,115,167,190,202,214,227,233,248,251,250,233,235,245,186,106,129,199,163,128,94,41,40,71,133,137,130,121,124,150,197,152,133,133,109,121,90,103,106,104,110,110,82,82,89,31,40,16,36,66,65,47,45,51,23,37,61,65,93,108,166,175,188,220,220,217,226,238,253,],
[238,194,131,110,116,119,96,86,95,115,157,183,102,90,112,88,97,106,104,63,44,16,16,43,61,63,47,60,76,111,99,130,122,108,137,122,129,105,74,106,119,130,130,124,142,185,221,251,252,244,219,226,244,195,102,105,206,158,119,90,49,47,82,130,129,124,96,93,112,104,78,85,75,95,97,126,109,88,96,92,114,121,113,74,52,61,43,5,22,29,16,35,45,82,83,90,92,89,80,95,108,139,164,174,164,180,202,245,],
[183,113,109,113,146,98,97,103,104,129,153,161,108,86,92,96,118,123,133,93,79,60,49,10,41,21,51,57,104,105,116,108,108,129,165,168,139,131,88,110,134,143,141,156,154,195,232,250,250,244,238,225,243,196,102,125,202,165,136,92,47,38,94,110,95,74,41,55,79,116,124,141,147,173,181,191,184,169,175,150,151,140,123,89,68,68,13,20,18,65,111,78,111,152,160,86,47,68,83,96,111,105,134,169,142,113,138,240,],
[197,126,131,103,94,120,118,109,97,103,146,139,105,100,122,108,140,158,186,152,69,155,124,94,16,10,17,21,50,147,130,94,93,129,169,199,171,136,97,110,121,201,223,220,232,236,237,233,236,247,252,250,249,187,108,136,192,160,146,102,40,42,76,84,67,66,57,91,156,208,217,238,248,252,229,233,235,250,254,238,237,218,227,217,184,86,52,10,45,148,146,81,106,149,136,127,83,82,83,106,92,108,115,109,152,151,137,238,],
[196,102,127,163,161,119,109,101,132,128,164,132,120,81,85,132,156,170,181,198,173,121,183,208,123,53,25,35,43,122,140,129,90,88,118,150,189,142,108,137,142,208,238,218,249,255,253,232,221,237,252,255,234,168,103,139,190,158,136,90,52,39,42,75,94,118,117,147,191,232,233,245,244,255,239,237,233,247,254,241,233,222,198,180,124,92,86,74,123,152,108,80,94,82,89,83,78,94,67,61,62,68,89,119,117,127,150,236,],
[175,125,184,213,130,118,90,102,121,129,134,146,158,118,119,144,150,144,169,212,224,173,128,199,219,198,144,59,81,68,110,133,136,117,111,119,111,114,111,112,143,211,250,239,237,246,247,243,231,231,247,244,230,170,103,121,160,125,101,82,35,44,79,137,136,114,104,125,183,223,233,250,245,251,233,227,233,252,235,220,147,123,139,105,112,83,103,112,131,98,124,83,95,89,79,102,84,76,73,88,61,34,45,103,95,121,115,228,],
[208,191,221,190,160,134,109,140,139,110,131,123,155,152,147,167,149,157,161,193,177,181,146,114,191,246,253,190,137,103,89,66,111,112,88,86,108,74,53,65,145,214,237,255,247,235,222,249,255,241,245,224,210,132,74,104,144,113,76,53,56,57,98,161,160,122,108,106,159,226,251,242,220,234,246,254,247,212,156,133,141,129,113,127,97,112,96,111,120,173,122,98,102,91,85,85,103,65,56,51,84,69,19,64,98,103,128,247,],
[247,234,223,165,134,135,126,157,122,93,83,135,163,148,152,148,174,142,144,133,80,130,147,136,129,205,255,238,227,181,129,81,72,82,78,58,14,55,70,125,151,140,171,213,230,228,223,250,255,241,231,189,159,102,90,111,104,87,88,84,69,79,117,160,153,116,109,106,133,169,226,253,230,228,246,238,179,139,114,135,135,101,118,114,126,87,118,97,154,152,107,99,93,96,113,120,86,74,34,16,25,55,70,29,53,85,132,234,],
[240,255,240,167,133,111,148,105,67,56,66,112,174,183,159,145,143,128,131,122,145,129,109,127,134,181,218,240,255,243,233,172,68,47,55,59,58,62,54,147,193,123,124,179,202,189,185,187,182,181,170,138,114,116,151,154,120,114,105,76,62,68,84,129,147,131,118,127,110,133,168,193,232,247,221,149,111,148,142,105,93,169,172,133,104,105,106,123,136,160,109,96,101,115,141,165,150,83,88,78,24,28,42,52,69,74,105,234,],
[251,250,197,170,128,98,140,136,140,96,67,71,130,155,140,152,147,134,152,167,173,140,130,85,114,153,188,229,241,255,249,171,118,101,44,51,65,44,51,87,175,141,108,188,200,125,87,75,76,90,87,86,75,140,197,172,136,143,116,67,56,65,81,159,208,191,140,142,110,119,115,160,252,197,128,127,137,123,81,153,174,233,165,131,114,106,126,130,176,115,100,100,84,136,164,156,193,134,128,176,101,32,3,29,20,109,117,241,],
[252,250,219,147,130,100,100,129,128,134,117,67,87,146,168,161,138,135,144,147,133,132,123,118,86,82,133,172,234,251,236,171,120,154,141,69,47,45,51,83,151,140,145,193,202,123,60,67,74,68,62,72,84,156,201,169,140,140,112,85,62,50,84,153,211,185,141,139,126,122,114,159,180,133,141,143,90,110,197,238,227,189,148,131,101,117,110,128,126,104,110,80,86,142,160,177,174,220,134,158,219,120,53,22,31,57,148,244,],
[243,226,184,163,137,105,85,105,129,147,140,109,123,149,169,146,117,113,139,129,130,136,135,177,123,117,148,145,207,231,247,195,144,135,174,139,89,40,34,63,125,136,112,137,166,157,137,140,132,126,128,137,126,158,148,143,143,131,110,67,58,67,74,134,181,165,129,121,142,159,158,123,94,131,112,107,127,209,234,239,252,175,148,109,121,119,131,150,97,113,119,86,84,112,163,186,220,235,244,132,162,225,202,100,60,69,110,231,],
[255,226,182,154,108,82,70,94,110,96,97,109,114,135,150,149,101,132,148,119,58,66,88,151,142,104,145,160,187,226,228,248,182,116,157,181,120,69,46,48,75,106,89,90,160,201,212,230,238,233,218,197,220,207,131,136,178,178,164,92,49,50,60,98,100,125,133,138,197,228,168,121,137,103,104,162,220,230,229,239,240,179,123,93,133,134,132,131,102,123,127,101,99,132,165,163,226,255,241,209,114,209,252,224,139,105,77,221,],
[246,225,190,98,103,99,95,97,97,93,108,120,133,123,156,159,122,112,145,142,140,109,85,130,142,102,103,148,175,186,240,240,182,148,164,158,143,93,60,80,91,86,83,87,163,226,236,246,251,250,248,233,245,217,131,131,201,228,208,122,58,33,59,80,78,130,146,168,223,211,147,111,110,83,182,235,246,233,235,227,203,147,144,89,89,146,144,140,116,102,107,102,95,115,142,195,221,249,244,230,189,134,242,255,224,177,143,234,],
[240,242,188,78,72,73,101,134,135,133,139,126,103,104,138,143,157,161,169,138,160,163,136,100,163,121,79,140,160,192,208,218,172,131,170,181,156,102,51,69,122,128,104,76,174,247,252,238,228,233,249,252,249,209,150,128,172,192,169,119,69,69,106,120,133,151,150,181,215,131,80,96,89,178,242,242,223,248,255,251,179,154,131,115,112,129,99,120,101,125,122,104,115,137,169,205,231,225,252,241,255,167,161,247,251,238,227,252,],
[243,247,158,93,116,94,116,152,117,107,130,137,130,142,158,167,174,181,183,196,195,180,160,125,108,151,100,77,140,158,179,210,163,148,169,169,145,87,60,90,143,127,89,102,177,247,252,233,224,236,249,250,240,199,177,143,129,99,78,82,83,85,104,106,114,133,180,199,140,75,94,69,176,248,230,223,247,248,246,236,175,128,135,154,109,109,114,135,130,151,122,94,84,106,194,223,218,229,235,253,247,232,127,200,252,251,247,252,],
[248,207,140,128,117,116,135,145,84,101,145,154,144,165,180,166,192,197,191,189,213,204,202,169,123,146,150,128,153,124,98,133,195,152,173,179,141,90,59,104,169,163,97,81,183,238,249,240,234,242,247,253,252,236,241,205,139,57,36,47,37,34,66,90,120,179,232,187,111,99,83,176,251,234,246,230,241,229,249,235,161,142,107,141,148,138,121,100,115,129,117,109,88,121,184,236,229,241,230,239,246,248,220,143,236,242,245,250,],
[235,140,139,155,117,117,136,158,104,123,153,152,157,171,163,176,180,192,167,186,187,201,202,215,170,122,124,138,129,108,96,98,176,177,161,165,149,96,38,103,163,155,108,91,184,214,231,250,255,249,225,219,236,248,255,228,160,86,95,100,96,98,126,121,144,206,210,133,90,87,187,240,231,226,253,244,254,240,218,214,174,124,109,122,130,138,103,103,111,124,108,86,85,125,193,219,255,247,245,227,221,254,232,205,183,237,233,254,],
[181,106,151,128,119,131,143,138,123,145,142,151,151,163,168,177,186,179,191,183,197,197,211,209,231,185,157,116,138,153,151,114,167,179,178,167,145,98,54,105,165,148,100,96,172,221,235,246,255,249,230,230,244,254,255,202,143,75,109,112,95,103,133,117,121,189,182,108,56,159,254,238,222,227,253,244,250,229,216,200,153,156,130,133,150,125,77,87,131,138,114,95,98,122,198,239,247,254,246,232,228,244,251,242,174,219,236,253,],
[198,98,134,149,114,138,138,128,142,146,148,151,155,159,167,189,201,195,191,187,199,213,203,211,210,234,203,146,128,143,161,185,167,170,172,161,141,97,55,107,167,149,99,94,177,240,245,238,243,241,244,238,241,244,240,211,143,71,91,87,76,81,83,94,108,158,149,79,96,218,241,239,248,251,238,241,241,243,253,223,176,143,125,114,140,106,92,107,124,131,107,98,106,125,212,241,236,237,241,243,241,241,238,237,192,207,245,253,],
[220,125,116,151,128,133,139,150,165,137,153,158,165,159,158,178,185,193,185,197,200,183,185,196,222,187,217,161,109,144,152,177,167,174,173,162,143,98,55,107,167,150,101,96,177,254,251,230,227,230,254,249,243,222,231,246,166,113,142,113,65,60,100,104,129,144,126,108,189,241,221,242,248,249,227,239,226,247,255,205,144,108,132,153,151,105,118,120,107,118,103,104,110,126,234,251,232,223,238,254,251,239,226,233,221,198,248,252,],
[244,198,125,132,142,111,128,160,147,135,161,155,163,148,131,136,150,191,190,211,197,169,180,150,185,195,226,192,104,121,144,156,200,178,168,163,147,98,52,102,164,149,102,99,179,253,250,239,230,235,251,255,243,232,239,244,152,97,137,119,75,77,104,122,117,154,134,191,255,234,231,247,242,245,233,242,233,248,247,212,152,131,133,163,153,105,123,110,93,102,103,102,96,109,238,255,237,228,240,251,246,242,228,236,245,197,232,250,],
[243,241,133,102,121,93,109,125,95,144,160,137,142,131,105,89,117,186,196,211,185,161,147,167,176,165,193,214,102,89,143,131,170,187,193,168,148,97,48,98,160,147,101,97,177,232,235,248,244,246,232,240,233,255,249,229,176,97,102,103,90,103,97,121,139,186,187,229,240,242,253,243,238,246,240,245,247,235,223,197,149,141,120,163,141,98,112,103,106,98,108,105,82,86,219,245,246,245,243,234,232,249,244,242,248,199,205,251,],
[245,250,149,99,83,89,108,100,73,143,139,132,147,152,128,81,100,167,196,213,187,164,183,191,202,187,167,197,140,72,132,153,158,178,165,163,146,97,52,102,162,147,100,96,177,219,225,248,254,252,221,223,234,255,254,234,209,127,116,122,86,94,111,115,184,228,224,220,229,255,253,242,222,233,247,252,244,227,232,208,172,144,111,157,135,98,103,103,116,96,107,107,90,85,206,238,252,255,245,224,225,252,255,245,239,208,188,252,],
[243,242,148,89,66,82,107,93,85,134,122,134,163,180,163,100,114,161,203,222,208,192,169,187,208,212,196,189,140,58,101,108,115,159,156,172,142,98,57,105,162,144,98,98,182,234,238,243,251,247,239,236,246,244,249,237,203,122,114,126,76,80,98,117,178,245,226,231,251,247,243,248,228,233,247,254,250,237,240,214,179,131,97,141,117,94,100,98,102,94,100,98,95,94,209,242,246,244,243,236,234,244,246,244,238,232,195,244,],
[247,246,147,80,67,68,90,75,91,132,126,129,148,164,157,102,132,168,208,218,222,206,188,175,194,202,215,208,165,65,118,108,112,132,150,167,138,97,57,104,156,137,95,98,178,248,250,229,233,228,255,253,245,226,231,250,246,158,106,103,80,84,91,132,195,236,250,255,249,224,235,242,252,251,230,235,233,247,254,227,168,109,90,149,90,88,106,102,92,107,107,96,81,93,211,245,235,226,241,255,247,234,230,243,246,255,211,235,],
[243,255,155,74,86,89,89,89,89,137,135,143,143,151,142,136,149,177,218,208,228,207,216,210,211,216,208,239,203,88,129,170,136,145,160,165,138,106,58,107,159,148,101,108,185,252,254,238,221,232,254,254,243,222,221,250,244,183,132,128,88,88,104,138,205,225,247,253,255,220,225,242,249,247,247,222,241,249,255,235,177,96,97,134,93,104,94,79,112,98,112,116,89,103,217,255,234,222,238,255,255,238,220,228,254,255,221,237,],
[250,240,139,105,103,100,90,90,103,160,159,168,164,161,155,144,154,171,208,207,216,221,203,202,216,210,214,205,213,149,142,177,150,162,162,150,134,93,62,109,158,123,75,103,176,235,240,243,241,246,242,244,241,242,245,251,242,209,182,181,147,157,165,194,236,237,247,234,239,235,242,240,246,242,238,238,244,244,247,248,189,89,116,89,101,136,110,108,136,120,131,130,78,100,214,249,237,236,241,238,242,239,239,240,246,238,234,245,],
[254,216,119,129,121,120,99,90,109,170,167,177,169,159,160,145,147,159,203,223,199,222,194,196,218,213,229,209,213,167,135,167,160,170,136,90,70,64,52,86,122,75,54,95,191,232,232,244,253,249,227,226,241,251,245,224,221,231,243,248,227,225,210,233,253,244,247,227,231,255,253,240,234,227,244,253,241,238,225,234,204,139,102,89,112,146,157,164,151,174,181,113,67,85,199,244,245,251,248,232,230,240,255,250,236,220,242,250,],
[250,211,124,133,139,148,119,93,106,166,160,168,171,162,158,132,111,123,168,205,192,211,195,195,209,212,216,224,222,169,158,181,184,184,138,86,70,78,54,83,117,75,66,86,125,139,139,178,225,223,203,178,186,195,190,168,169,182,190,181,184,184,186,227,241,233,224,208,222,247,235,232,217,213,255,254,240,241,227,226,220,177,81,116,116,151,224,222,163,211,224,128,72,79,191,245,249,248,245,237,235,240,254,249,234,223,240,253,],
[247,232,168,137,146,158,120,79,91,158,152,158,166,164,154,127,94,112,150,185,192,205,193,194,200,212,202,219,207,173,165,180,183,179,148,118,93,62,25,67,122,112,80,72,80,63,53,96,148,142,160,146,148,148,156,154,163,159,153,138,151,142,140,157,162,178,177,183,173,184,181,187,186,193,217,223,229,243,244,247,231,164,105,138,104,152,229,248,235,253,220,105,82,90,202,249,239,229,236,244,248,240,239,240,242,245,237,255,],
[249,254,220,147,143,148,102,61,80,157,154,158,160,166,162,148,130,151,181,196,210,225,199,198,203,216,210,208,206,202,161,173,188,188,156,124,113,64,49,74,115,127,80,61,63,46,48,92,138,120,139,137,140,127,133,134,138,120,114,104,111,109,113,123,145,181,176,176,185,183,187,175,179,182,156,181,221,251,248,255,229,173,125,155,114,184,221,234,248,249,226,109,73,94,211,249,230,223,239,253,251,237,228,232,247,255,236,255,],
[252,249,237,143,142,139,96,66,87,161,158,161,164,174,176,165,158,159,180,171,205,224,215,206,211,211,214,204,214,215,183,172,182,183,153,113,102,71,87,111,125,121,104,83,73,60,42,49,82,81,72,74,70,59,69,71,78,64,66,57,58,60,62,75,102,123,115,112,114,111,119,111,113,123,108,144,201,250,242,241,234,214,138,170,150,217,232,236,251,255,235,99,65,85,204,247,237,234,244,249,244,239,234,233,244,246,237,252,],
[253,229,226,128,136,131,97,75,93,155,148,152,159,168,175,155,148,124,140,116,149,176,214,208,216,207,212,214,208,205,226,178,155,150,145,122,117,85,99,150,152,104,115,86,81,101,81,35,32,44,20,40,36,24,29,21,30,28,38,27,33,37,31,39,45,32,32,44,39,38,39,47,35,52,86,115,151,220,234,230,254,242,183,191,170,234,253,244,238,235,214,115,72,80,193,247,249,243,239,231,239,247,248,240,241,231,241,247,],
[255,228,211,112,105,73,72,91,113,158,169,157,155,165,165,142,148,140,154,152,138,147,157,196,223,221,205,219,215,201,175,157,145,173,148,126,115,81,85,121,136,109,94,79,82,127,118,100,61,58,46,67,59,65,66,70,63,62,58,72,67,57,55,68,65,50,55,66,61,53,50,69,54,77,139,118,146,212,229,237,246,255,209,217,206,248,255,244,223,229,227,103,92,66,178,242,247,254,246,223,230,243,255,252,226,230,237,252,],
[241,226,224,113,85,121,96,82,75,135,167,151,155,165,176,163,138,165,182,187,199,198,188,184,213,218,215,216,207,169,104,136,182,188,137,114,122,99,79,85,102,103,99,84,82,113,124,134,105,72,83,71,70,70,74,95,91,77,65,83,73,68,74,70,68,76,73,71,78,75,61,65,67,108,180,186,188,239,238,243,243,247,233,246,229,249,241,242,240,235,218,105,101,82,187,247,242,242,242,235,238,240,244,241,242,238,238,253,],
[244,255,255,134,91,78,75,112,71,129,165,164,151,151,163,160,139,170,165,168,178,207,222,211,216,211,216,223,204,137,68,141,193,158,118,132,110,100,84,98,105,90,77,82,163,205,211,202,170,150,174,155,164,146,132,138,116,81,77,91,78,62,71,67,76,113,132,147,150,147,114,88,92,141,211,240,228,255,251,246,231,227,245,253,250,245,219,234,255,249,220,121,104,102,202,253,234,228,240,250,251,236,228,229,255,249,242,254,],
[246,239,251,206,90,60,64,109,98,134,165,156,158,158,167,158,161,166,173,198,193,216,224,228,218,213,204,215,208,120,92,163,199,162,143,162,141,102,60,85,108,93,77,97,198,255,251,234,221,241,241,249,237,221,210,207,152,77,89,83,82,65,74,82,111,178,225,247,232,221,188,168,184,216,232,224,229,253,248,242,229,228,252,247,251,240,217,233,254,255,220,121,93,112,212,253,231,229,241,252,255,236,227,230,253,252,245,255,],
[255,232,238,235,156,90,113,101,98,143,160,153,153,151,155,151,166,162,182,199,212,218,214,221,217,215,206,212,182,114,138,168,191,169,150,156,133,107,72,93,114,102,83,95,203,242,211,221,230,247,235,252,239,245,249,230,147,63,106,82,73,78,86,91,119,188,243,248,238,249,253,240,233,242,246,236,239,234,238,241,241,243,246,235,236,244,241,243,238,245,208,105,78,106,211,247,238,244,243,233,243,239,243,246,237,239,241,253,],
[246,237,235,218,243,147,110,117,97,151,160,168,155,147,147,154,155,167,183,171,190,204,220,216,218,209,211,211,151,127,169,174,189,156,138,163,151,110,69,91,125,120,88,68,136,140,93,109,128,151,215,236,228,255,246,184,91,52,112,71,56,73,84,86,93,138,201,226,236,245,250,240,226,233,248,249,255,228,231,242,251,252,235,230,226,248,255,246,225,236,204,107,81,97,207,240,246,255,243,219,230,242,255,255,228,227,234,250,],
[241,228,239,251,239,231,105,106,125,152,164,161,155,148,149,146,131,151,169,174,188,198,211,205,205,196,196,191,112,127,151,165,179,143,137,161,147,110,88,110,136,119,85,50,73,71,38,31,35,73,198,237,230,251,233,184,118,117,133,94,83,91,107,110,110,136,188,232,230,247,251,245,230,224,239,250,247,229,233,239,247,252,237,244,232,247,247,241,232,242,195,107,103,98,213,238,245,250,241,230,233,241,252,248,236,231,234,250,],
[251,243,239,244,231,244,196,103,143,159,155,150,161,148,146,135,137,142,135,154,154,169,181,193,182,181,180,189,85,147,161,172,163,135,150,149,143,109,96,115,143,133,95,36,59,70,74,66,56,88,199,254,252,237,225,243,224,226,194,183,194,191,203,197,201,221,229,246,242,246,232,241,255,246,241,236,231,242,248,240,234,242,236,247,244,246,234,239,249,249,176,85,125,105,224,240,237,235,240,253,245,240,237,231,249,244,240,252,],
[244,248,255,247,227,223,238,185,140,158,154,155,151,154,145,149,136,129,120,117,113,133,158,157,163,161,182,181,102,153,154,176,198,137,139,154,144,113,89,112,155,133,94,75,131,161,90,47,73,147,231,255,229,228,222,255,253,249,225,224,236,250,255,244,228,234,249,255,245,229,226,239,249,255,231,223,233,255,255,241,232,222,247,251,255,234,220,246,243,255,178,77,105,105,237,255,228,232,238,252,254,233,222,232,253,254,242,247,],
[253,242,242,248,242,231,244,219,160,159,154,151,143,147,141,147,138,130,121,115,118,116,131,137,157,189,224,168,87,155,157,197,207,142,138,149,141,115,91,104,156,144,97,79,178,220,137,101,154,228,248,240,251,245,230,237,243,252,246,243,236,239,246,243,233,233,240,250,247,237,232,241,248,243,239,236,236,249,246,238,236,232,247,238,246,234,232,245,248,247,172,74,112,116,221,244,235,232,241,249,247,240,236,235,244,246,243,255,],
[254,230,223,239,255,243,245,232,167,158,154,142,146,146,137,140,132,128,126,125,127,142,163,179,203,211,230,151,109,148,166,240,213,139,143,142,142,115,97,113,159,139,97,99,191,230,161,135,172,236,240,231,236,248,252,236,230,228,242,253,243,228,235,243,251,246,232,232,243,250,248,241,237,226,248,252,245,237,230,238,249,247,247,224,237,239,248,238,241,230,163,79,96,113,207,245,255,249,245,228,232,245,252,242,234,232,237,255,],
[253,231,225,235,253,249,244,208,157,160,160,146,153,155,150,154,154,157,168,174,192,208,211,210,216,205,220,135,116,148,190,255,211,135,143,143,142,116,100,121,158,136,107,107,176,214,149,130,189,249,233,219,253,248,248,235,235,234,245,255,246,224,225,232,253,252,229,220,236,255,255,239,226,224,247,255,250,227,221,242,255,252,245,223,235,245,255,236,237,224,155,85,105,115,202,232,252,248,247,222,226,244,255,247,235,227,230,251,],
[247,241,242,236,234,244,245,184,154,163,166,165,168,173,175,180,182,183,197,205,217,216,216,212,210,213,225,117,107,168,220,241,206,137,134,151,139,117,97,117,155,146,123,92,181,248,161,100,180,242,233,245,244,239,246,250,242,240,237,245,248,243,245,233,244,246,241,242,239,241,243,239,234,243,238,240,241,234,236,246,239,238,243,239,239,243,248,238,249,245,153,81,134,128,224,241,242,236,245,239,240,240,243,243,245,241,237,251,],
[243,246,252,240,226,236,239,178,161,160,164,176,184,188,189,186,185,181,195,202,202,208,211,213,219,215,214,156,164,196,235,229,201,137,135,150,139,114,101,125,160,145,116,88,192,251,166,107,178,237,242,249,223,197,195,213,214,235,229,229,229,247,255,234,233,226,241,254,248,226,222,240,252,255,231,227,232,250,255,248,221,227,245,255,249,234,228,230,254,255,154,81,129,124,241,255,244,226,238,254,254,235,224,232,250,253,245,255,],
[250,248,250,248,237,229,212,171,161,162,171,178,190,192,193,190,193,188,202,206,221,226,213,204,212,202,205,232,238,225,241,238,203,136,141,146,143,112,109,132,167,136,82,81,194,236,166,127,163,226,255,249,170,149,178,214,198,198,185,187,214,221,216,215,237,229,249,255,248,232,228,242,253,251,236,231,237,251,255,246,227,235,243,254,252,232,230,231,247,250,148,92,111,122,235,238,236,225,238,253,252,235,226,232,247,248,242,253,],
[251,239,236,246,251,225,182,158,156,170,189,181,193,196,200,200,204,194,201,198,208,209,212,212,219,224,221,250,246,250,250,243,210,137,140,149,146,115,115,122,167,138,54,58,194,231,144,121,173,239,221,159,92,62,120,199,213,213,200,201,186,161,132,156,218,224,242,235,240,250,250,242,240,231,246,243,247,238,231,241,245,249,236,239,244,235,253,246,244,231,140,102,108,141,244,234,246,243,245,238,241,240,242,243,245,238,234,250,],
[255,231,224,232,239,197,149,163,163,167,181,178,194,200,206,197,203,190,203,194,202,213,217,208,206,207,239,252,228,215,233,254,218,139,146,151,144,119,107,128,163,114,39,61,167,178,113,97,127,154,125,77,31,20,52,91,146,190,195,228,217,212,197,181,197,213,206,215,227,254,255,231,233,232,241,254,253,230,224,234,255,252,238,223,234,249,255,240,237,221,120,103,116,124,218,233,254,255,236,233,226,240,255,248,237,221,233,252,],
[239,235,240,244,210,165,178,158,165,176,168,182,186,196,205,211,209,192,194,190,204,208,213,213,213,213,239,247,234,235,238,240,212,139,141,154,142,125,107,134,167,110,38,46,135,111,74,90,67,40,36,38,21,18,20,34,53,75,116,165,186,211,222,211,206,201,187,183,197,219,248,251,229,230,246,252,240,241,231,240,247,247,242,225,239,246,246,237,245,214,126,108,105,136,237,239,245,252,241,236,234,245,253,243,237,229,240,252,],
[250,250,244,243,160,164,182,162,169,162,170,180,189,200,206,218,214,206,200,196,202,200,210,216,212,210,230,232,253,255,245,229,205,143,143,162,137,122,95,127,163,111,52,52,141,98,55,75,54,24,18,21,19,27,31,27,18,12,29,54,106,141,171,193,211,221,220,207,204,192,200,231,235,248,248,240,227,253,245,246,231,234,246,240,251,235,235,230,255,218,126,108,98,147,252,245,231,235,241,247,248,240,236,234,245,243,247,251,],
[255,244,248,249,178,148,179,190,174,167,172,180,194,201,203,210,214,220,217,210,204,204,216,219,206,208,226,226,249,249,242,228,192,135,137,149,135,124,105,133,163,124,81,86,174,178,129,119,117,96,45,14,13,9,32,23,14,14,35,83,111,120,124,131,132,144,176,186,201,198,182,198,235,251,229,217,231,253,253,244,224,227,246,255,255,229,231,228,255,221,117,104,101,151,250,249,229,224,237,255,255,234,222,230,254,253,250,250,],
[244,239,254,242,168,170,194,180,170,167,168,184,191,193,202,207,216,219,219,218,214,213,221,217,206,222,239,238,248,239,253,251,193,138,146,149,137,122,111,130,160,143,116,132,200,250,230,219,226,212,150,112,98,59,51,35,28,24,52,103,97,102,107,105,68,41,64,87,112,130,129,146,216,248,242,237,246,237,243,237,239,238,240,250,243,239,236,242,248,197,111,103,103,151,237,247,241,236,238,246,249,240,235,236,249,245,246,248,],
[244,241,233,225,158,180,199,163,164,161,172,183,192,193,211,218,220,211,209,217,217,213,213,209,208,238,252,250,238,224,234,224,161,122,138,143,128,104,92,117,158,149,106,97,131,204,238,254,254,255,231,214,215,194,172,157,153,133,137,120,123,103,100,112,93,53,33,26,35,37,71,133,209,235,248,255,255,223,229,234,255,254,234,232,225,254,245,255,237,160,110,110,98,157,229,240,250,254,240,227,233,249,255,242,234,227,237,245,],
[249,233,220,234,223,157,186,183,168,171,171,178,193,199,211,216,212,216,210,217,210,208,209,209,214,242,248,249,237,223,197,164,128,114,125,134,113,93,78,114,154,130,72,32,76,149,214,252,241,239,232,232,240,255,255,233,227,214,210,166,125,102,114,159,192,183,143,113,99,101,146,206,230,227,237,254,249,229,230,239,252,251,234,231,229,252,249,251,232,147,105,115,99,174,236,236,246,252,241,229,229,245,255,244,234,224,235,247,],
[251,237,244,247,230,216,177,183,173,157,161,172,186,197,196,195,193,227,221,220,205,208,216,221,222,241,239,245,241,232,174,125,121,125,118,122,108,96,68,97,127,109,85,58,72,100,137,197,216,215,198,203,211,205,216,198,209,217,216,192,170,159,172,192,212,218,200,193,176,189,198,206,200,214,226,238,238,243,243,246,235,236,237,246,246,237,249,236,233,158,97,116,108,194,250,239,238,240,241,248,239,235,240,245,249,236,241,255,],
[254,245,254,245,233,224,218,197,159,174,167,170,172,184,181,178,172,189,219,220,205,212,217,217,223,238,225,226,253,240,158,119,143,147,140,130,112,100,97,103,139,156,113,85,111,91,96,145,143,141,153,144,139,131,113,107,114,110,107,119,117,113,113,119,121,116,118,131,125,128,121,125,126,158,205,224,227,255,254,246,227,219,249,254,255,220,222,233,244,149,96,124,105,212,251,245,229,224,242,254,252,238,224,227,249,252,243,255,],
[253,249,252,247,224,230,247,228,168,166,164,169,164,170,184,187,190,179,204,200,212,209,215,229,218,219,230,239,242,205,134,128,141,139,135,136,120,99,77,76,111,136,102,82,102,87,81,102,87,88,108,103,82,68,42,28,28,23,22,35,26,28,31,34,33,28,33,47,49,42,50,59,63,112,198,236,233,251,255,239,233,230,250,249,244,240,235,240,231,140,110,132,111,218,250,245,235,232,241,249,247,240,232,232,246,249,243,252,],
[250,228,224,249,251,255,246,207,163,163,153,158,171,164,170,179,195,191,215,210,214,209,213,228,209,218,251,253,235,173,97,100,113,133,127,116,82,54,24,42,103,138,91,57,60,64,81,113,108,108,120,113,98,88,69,60,62,58,56,65,59,58,57,60,66,66,66,71,75,70,80,83,86,116,193,241,244,238,242,233,246,242,243,233,231,255,245,247,220,124,110,114,115,219,238,238,246,246,240,235,237,243,249,242,238,237,237,249,],
[247,245,225,229,248,249,245,205,155,174,191,186,165,166,164,180,189,203,222,216,198,199,208,221,203,214,241,248,220,166,106,102,108,124,117,108,88,76,52,61,100,126,92,74,63,69,99,144,153,144,143,136,142,139,134,136,142,140,138,143,135,132,128,130,140,143,140,138,130,139,136,139,147,145,172,223,251,232,223,235,255,249,238,221,230,254,250,251,211,104,102,101,116,220,228,233,253,255,240,227,231,243,255,250,233,226,232,251,],
[246,235,227,252,251,249,221,188,179,195,197,200,211,212,203,200,187,191,217,223,213,204,208,215,203,206,219,249,222,158,106,105,121,119,113,128,137,140,124,114,118,122,105,104,104,98,106,123,129,123,126,126,125,121,119,121,126,126,125,128,122,125,123,123,126,128,128,130,124,135,126,137,138,132,134,183,241,243,226,244,247,243,243,231,241,242,247,248,201,91,101,106,117,233,238,239,247,247,240,239,240,238,244,244,238,233,238,255,],
[243,239,226,213,191,175,173,177,172,188,210,216,213,214,226,228,221,195,210,206,210,208,208,211,217,226,215,232,215,153,105,96,118,118,115,140,149,150,142,133,137,133,119,108,110,112,112,103,105,105,110,111,112,108,108,110,111,110,109,108,115,116,113,114,118,119,118,121,116,117,113,128,110,114,119,159,223,255,243,249,229,232,250,249,251,227,231,242,192,93,100,89,122,247,253,246,233,228,237,254,253,235,226,232,247,251,247,255,],
[221,182,177,171,157,150,145,163,189,196,197,202,210,208,219,227,236,222,239,230,232,244,240,235,232,231,203,187,192,177,161,132,113,116,114,139,151,146,143,128,129,122,124,113,107,115,120,108,112,109,107,105,107,105,107,111,111,110,109,106,115,112,107,110,116,117,115,117,117,118,118,127,113,119,125,163,221,250,249,248,227,228,247,254,248,228,226,242,173,96,105,71,134,251,250,247,231,227,237,253,251,239,229,231,249,254,245,253,],
[219,184,194,181,193,192,187,182,181,187,205,212,213,222,222,227,221,223,232,220,206,219,210,208,197,198,210,215,210,210,201,161,111,117,113,135,157,146,144,128,130,119,123,104,114,112,111,102,112,107,106,113,115,110,109,111,110,112,114,112,115,116,116,117,118,114,118,128,118,127,120,117,121,122,120,162,233,239,245,247,240,234,239,249,240,243,236,247,149,91,117,81,146,248,237,244,242,241,242,242,237,246,246,240,246,243,236,250,],
[207,158,167,173,180,186,189,187,186,189,191,191,189,196,197,191,188,190,191,188,194,198,201,202,205,211,216,218,214,212,214,156,114,115,127,130,144,141,131,124,126,126,119,115,115,112,110,111,111,109,109,110,111,111,109,108,107,109,113,116,113,112,112,114,117,119,119,119,121,123,121,123,117,125,124,172,236,228,221,237,248,255,239,228,232,250,253,248,129,92,99,87,159,237,229,231,243,255,244,226,227,244,255,247,230,225,237,251,],
[211,163,170,175,166,172,175,175,176,180,183,183,182,184,187,190,191,193,197,201,211,217,221,222,222,221,218,215,218,222,225,162,105,95,113,129,148,145,134,126,126,124,116,111,114,112,112,113,112,110,110,111,114,112,110,110,112,113,113,113,113,113,114,115,117,119,119,119,117,118,118,125,118,120,118,165,232,234,236,243,244,245,237,233,234,245,252,246,130,102,103,67,160,238,223,239,255,253,241,226,233,242,251,249,241,236,239,245,],
[207,161,163,165,157,160,161,160,160,163,164,162,170,174,189,208,216,214,216,222,218,219,218,216,214,213,211,209,210,209,212,166,121,105,105,108,121,120,113,110,114,114,109,106,110,110,110,111,109,107,107,109,109,106,104,106,109,110,107,104,109,110,111,112,112,113,114,114,119,115,113,119,114,115,117,161,227,238,248,243,238,234,240,243,241,237,234,218,113,101,104,52,165,255,245,241,240,231,242,247,245,240,236,239,242,244,245,248,],
[208,169,165,165,173,174,173,171,170,170,169,166,171,178,196,218,226,221,218,221,222,219,215,213,213,215,217,218,217,211,216,206,196,191,178,167,163,161,152,146,144,138,129,126,132,133,135,134,132,130,131,133,129,127,126,128,131,132,128,125,131,132,133,133,132,132,133,135,131,129,128,137,138,144,149,182,234,245,254,241,237,234,247,252,254,239,219,193,113,109,111,63,166,248,252,247,235,227,244,255,253,239,230,234,244,249,251,253,],
[247,234,239,242,241,242,242,241,240,241,240,239,238,241,247,253,253,250,248,248,247,246,246,248,249,249,249,249,246,242,245,249,251,255,249,246,240,240,238,238,242,240,236,237,242,244,246,245,243,242,243,244,241,241,241,242,243,243,242,241,241,242,243,243,242,242,243,244,246,247,245,247,245,243,237,247,251,255,255,245,245,244,252,252,250,251,245,245,221,234,244,222,253,255,249,251,246,243,248,255,253,244,240,247,255,255,253,253,],
[255,252,255,255,253,255,255,255,255,255,255,255,255,255,255,254,252,252,252,251,252,252,253,254,254,252,251,252,255,255,253,255,251,253,252,255,255,255,253,254,255,255,252,253,253,255,255,254,253,254,254,254,252,253,254,254,253,253,254,255,254,254,255,254,254,254,254,255,249,252,251,252,254,255,252,252,255,255,254,250,254,255,255,250,250,255,252,253,251,254,255,248,255,240,246,255,255,255,254,247,254,251,251,255,255,255,253,253,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,252,138,199,255,255,255,255,255,255,255,220,118,119,115,189,255,255,255,255,255,255,238,128,99,146,252,255,255,255,255,255,201,115,121,121,115,200,255,255,255,255,255,212,168,255,225,158,255,255,255,255,255,255,218,117,119,114,191,255,255,255,255,255,228,123,119,122,114,168,255,255,255,255,255,255,152,117,117,157,255,255,255,255,255,255,255,234,128,101,176,255,255,255,255,255,255,251,151,99,124,237,255,255,255,],
[255,255,255,255,214,10,94,255,255,255,255,255,255,255,177,47,177,171,215,255,255,255,255,255,255,106,105,188,146,246,255,255,255,255,255,220,173,79,77,173,220,255,255,255,255,255,167,82,255,199,60,255,255,255,255,255,255,173,48,177,171,216,255,255,255,255,255,238,176,117,43,168,200,255,255,255,255,255,255,195,73,78,199,255,255,255,255,255,255,252,78,118,179,165,255,255,255,255,255,255,156,72,188,146,224,255,255,255,],
[255,255,255,255,145,98,73,236,255,255,255,255,255,255,179,66,214,210,240,255,255,255,255,255,255,68,146,255,255,255,255,255,255,255,254,255,255,132,129,255,255,255,255,255,255,255,173,67,212,153,66,255,255,255,255,255,255,175,68,214,210,240,255,255,255,255,255,255,255,189,79,255,255,255,255,255,255,255,255,255,127,134,255,255,255,255,255,255,255,203,54,254,255,255,255,255,255,255,255,255,119,94,253,255,255,254,255,255,],
[255,255,255,255,81,199,93,181,255,255,255,255,255,255,183,24,91,86,195,255,255,255,255,255,255,191,56,51,139,254,255,255,255,255,255,255,255,127,124,255,255,255,255,255,255,255,176,29,94,64,63,255,255,255,255,255,255,180,24,91,86,197,255,255,255,255,255,255,255,183,76,255,255,255,255,255,255,255,255,255,122,129,255,255,255,255,255,255,255,175,74,255,255,255,255,255,255,255,255,255,222,74,47,107,241,255,255,255,],
[255,255,255,229,28,97,44,115,255,255,255,255,255,255,177,86,255,255,255,254,255,255,255,255,254,255,254,205,42,192,255,255,255,255,255,255,255,127,124,255,255,255,255,255,255,255,170,89,255,202,67,255,255,255,255,255,255,173,89,255,255,255,255,255,255,255,255,255,255,183,76,255,255,255,255,255,255,255,255,255,124,131,255,255,255,255,255,255,255,190,63,255,255,255,255,255,255,255,255,254,255,255,225,70,139,255,255,255,],
[255,255,255,160,72,203,161,55,247,255,255,255,255,255,176,67,230,226,239,255,255,255,255,255,255,194,226,234,58,187,255,255,255,255,255,255,255,124,121,255,255,255,255,255,255,255,168,82,255,195,62,255,255,255,255,255,255,173,69,231,225,239,255,255,255,255,255,255,255,181,71,255,255,255,255,255,255,255,255,242,104,110,244,255,255,255,255,255,255,240,52,176,237,208,255,255,255,255,255,255,207,211,246,96,133,255,255,255,],
[255,255,255,133,169,255,253,96,219,255,255,255,255,255,200,56,74,66,153,255,255,255,255,255,255,141,66,64,119,250,255,255,255,255,255,255,255,155,153,255,255,255,255,255,255,255,189,123,255,209,108,255,255,255,255,255,255,197,55,74,66,156,255,255,255,255,255,255,255,199,115,255,255,255,255,255,255,255,255,118,59,59,125,255,255,255,255,255,255,255,194,73,66,138,255,255,255,255,255,255,179,66,67,90,233,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,247,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,243,255,255,255,255,255,255,255,255,251,242,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,],
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,]
]
ip = ByteProcessor(w, h)
for y in range(h):
for x in range(w):
value = img[y][x]
ip.putPixelValue(x, y, value)
imp = ImagePlus("Generated Image", ip)
return imp
# GenerateImg end
#------------------------------------------------------------------------------
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
# Main Program
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
#????????????????????????????????????????????????????????????????????????????????????
# Define flag
flagSave = 1
flagOpenDir = 0
flagFullColor = 0
flagExtactRedChannel = 0
imp = GenerateImg()
# Select Processing
gd = GenericDialog("Processing setting")
gd.addMessage("Select Processing")
gd.addMessage("")
gd.addMessage("- Main -")
gd.addCheckbox("Contrast Adjustment", False)
gd.addCheckbox("Change the Resolution ", False)
gd.addCheckbox("Nombre Cut", False)
gd.addCheckbox("Sharpen", False)
gd.addMessage("")
gd.addMessage("- Optimise minAndMax -")
gd.addMessage("")
gd.addCheckbox("Full Auto", False)
gd.addCheckbox("Manual 3 Trials", False)
gd.addCheckbox("Mokushi Now", False)
gd.addMessage("")
gd.addMessage("- Renumbering -")
gd.addMessage("")
gd.addCheckbox("Renumbering [from 1]", False)
gd.addCheckbox("Renumbering [Automator]", False)
gd.addMessage("")
gd.addMessage("- Rename -")
gd.addMessage("")
gd.addCheckbox("Add Suffix", False)
gd.addMessage("")
gd.addMessage("")
gd.addImage(imp)
gd.showDialog()
if gd.wasCanceled():
IJ.log("")
IJ.showMessage("Exit : Processing was canceled.")
raise RuntimeError("yamepi")
flagContr = gd.getNextBoolean()
flagReso = gd.getNextBoolean()
flagNombre = gd.getNextBoolean()
flagSharpen = gd.getNextBoolean()
flagOptMinMaxAuto = gd.getNextBoolean()
flagOptMinMax3Trials = gd.getNextBoolean()
flagOptMinMaxMokushi = gd.getNextBoolean()
flagRenumFrom1 = gd.getNextBoolean()
flagRenumATMT = gd.getNextBoolean()
flagAddSuffix = gd.getNextBoolean()
# print flag and set procTag
procTag = ""
if flagContr:
IJ.log("flagContr = ON")
procTag = procTag + "Contr"
if flagReso:
IJ.log("flagReso = ON")
procTag = procTag + "Reso"
if flagNombre:
IJ.log("flagNombre = ON")
procTag = procTag + "Nombre"
if flagSharpen:
IJ.log("flagSharpen = ON")
procTag = procTag + "Sharpen"
if flagOptMinMaxAuto:
IJ.log("flagOptMinMaxAuto = ON")
if flagOptMinMax3Trials:
IJ.log("flagOptMinMax3Trials = ON")
if flagOptMinMaxMokushi:
IJ.log("flagOptMinMaxMokushi = ON")
if flagRenumFrom1:
IJ.log("flagRenumFrom1 = ON")
procTag = procTag + "From1"
if flagRenumATMT:
IJ.log("flagRenumATMT = ON")
procTag = procTag + "ATMT"
if flagAddSuffix:
IJ.log("flagAddSuffix = ON")
procTag = procTag + "Suffix"
# check flag
if flagRenumFrom1 and flagRenumATMT:
IJ.showMessage("Exit : Two \"Renumbering Processing\" were selected.")
raise RuntimeError("yamepi")
if flagOptMinMax3Trials and flagOptMinMaxAuto and flagOptMinMaxMokushi:
IJ.showMessage("Exit : Three \"OptMinMax Processing\" were selected.")
raise RuntimeError("yamepi")
if (flagOptMinMax3Trials and flagOptMinMaxAuto) or (flagOptMinMax3Trials and flagOptMinMaxMokushi) or (flagOptMinMaxAuto and flagOptMinMaxMokushi):
IJ.showMessage("Exit : Two \"OptMinMax Processing\" were selected.")
raise RuntimeError("yamepi")
if flagOptMinMax3Trials or flagOptMinMaxAuto or flagOptMinMaxMokushi:
if not flagContr:
IJ.showMessage("Sorry. Only optMinMax processing are not supported")
raise RuntimeError("yamepi")
if not(flagContr or flagReso or flagNombre or flagSharpen):
if flagRenumFrom1 or flagRenumATMT:
IJ.showMessageWithCancel("Wait","Only Renumbering processing")
if flagOptMinMax3Trials or flagOptMinMaxAuto or flagOptMinMaxMokushi:
if not (flagContr or flagReso or flagNombre or flagSharpen or flagRenumFrom1 or flagRenumATMT):
flagSave = 0
IJ.log("flagSave = OFF")
if (flagContr or flagReso or flagNombre or flagSharpen or flagRenumFrom1 or flagRenumATMT or flagOptMinMaxAuto):
flagOpenDir = 1
else:
IJ.log("flagOpenDir = OFF")
if flagAddSuffix and flagRenumATMT:
IJ.showMessage("[flagAddSuffix and flagRenumATMT] are not supported.")
raise RuntimeError("yamepi")
if not (flagContr or flagReso or flagNombre or flagSharpen or flagRenumFrom1 or flagRenumATMT or flagOptMinMaxAuto or flagOptMinMax3Trials or flagOptMinMaxMokushi):
IJ.showMessage("Exit : Please Select any proc.")
raise RuntimeError("yamepi")
# Directory Selection
if flagOpenDir:
IJ.showMessage("openDir", "Select Directory for Processing")
openDir = IJ.getDirectory("Choose a directory")
IJ.log("")
IJ.log("Processing : " + openDir)
# Count totalFiles
totalFiles = 0
countFiles(openDir)
logWindow.toFront()
IJ.log("... totalFiles = " + str(totalFiles) + " Files")
if flagSave:
IJ.showMessage("saveDir", "Select Directory for Saving")
saveDir = IJ.getDirectory("Choose a directory")
IJ.log("Save to : " + saveDir)
IJ.log("")
logWindow.toFront()
time.sleep(1)
# Select Nombre Type
if flagNombre==1:
gd = GenericDialog("Nombre Cut setting")
items = ["Use One ROI", "Case Divided by ODD/EVEN"]
gd.addRadioButtonGroup("Select NombreCut Type", items, 2, 1, "Use One ROI")
gd.showDialog()
nombreRadio = gd.getNextRadioButton()
if nombreRadio == "Use One ROI":
NombreType = 1
elif nombreRadio == "Case Divided by ODD/EVEN":
NombreType = 2
# Clear ROI Manager and get ROI
if flagNombre:
rm = RoiManager() # open RoiManager
rm = RoiManager.getInstance()
roiCount = rm.getCount()
if roiCount > 0:
rm.reset() # delete all rois in RoiManager
if NombreType == 1:
roi1_nb = getRoiNombre1()
elif NombreType == 2:
roi1_nb, roi2_nb = getRoiNombre2()
# Enter parameter
if flagSave:
gd = GenericDialog("Processing Setting")
if not (flagOptMinMax3Trials or flagOptMinMaxAuto or flagOptMinMaxMokushi):
if flagContr:
gd.addNumericField("min (0-255)", 0)
gd.addNumericField("Max (0-255)", 255)
gd.addCheckbox("Full Color", False)
gd.addCheckbox("Extract Red Channel", False)
gd.addMessage("")
if flagReso:
gd.addNumericField("pre dpi", 600)
gd.addNumericField("post dpi(Target)", 400)
if flagAddSuffix:
gd.addStringField("Suffix", "suffix")
if flagRenumATMT or flagRenumFrom1:
gd.addNumericField("Digit of Page Number", 4)
gd.addRadioButtonGroup("Output format", ["JPEG", "PNG"], 1, 2, "JPEG")
gd.showDialog()
if gd.wasCanceled():
IJ.showMessage("Exit : Processing was canceled.")
raise RuntimeError("yamepi")
if not (flagOptMinMax3Trials or flagOptMinMaxAuto or flagOptMinMaxMokushi):
if flagContr:
min = int(gd.getNextNumber())
max = int(gd.getNextNumber())
flagFullColor = gd.getNextBoolean()
flagExtactRedChannel = gd.getNextBoolean()
if flagReso:
preDpi = int(gd.getNextNumber())
postDpi = int(gd.getNextNumber())
if flagAddSuffix:
suffix = gd.getNextString()
if flagRenumATMT or flagRenumFrom1:
digit = int(gd.getNextNumber())
output = gd.getNextRadioButton()
if flagFullColor and flagExtactRedChannel:
IJ.showMessage("flagFullColor and flagExtactRedChannel can't be used together.")
raise RuntimeError("yamepi")
if output == "JPEG":
ext = ".jpg"
elif output == "PNG":
ext = ".png"
# JPEG quality setting
quality = 90
ioOption = "jpeg=" + str(quality) + " gif=-1 file=.csv save_column save_row"
IJ.run("Input/Output...", ioOption);
if output == "JPEG":
IJ.log("JPEG quality =" + str(quality))
# SetResolution Setting
if flagReso:
compressionRate = float(postDpi) / preDpi
IJ.log(str(compressionRate))
# Reference setting
if flagRenumATMT:
referenceCheck(openDir)
# net processing time
initialTime = time.time()
# optimiseMinAndMax Manual 3 Trials
if flagOptMinMax3Trials:
min, max = showMeOptMinAndMax3Trials()
# optimiseMinAndMax Auto
if flagOptMinMaxAuto:
seqPageNum = 0 # Sequential Number (0 to totalFiles)
optAutoDetectCount = 0 # detecting images to be checked
min, max = showMeOptMinAndMaxAuto(openDir)
# optimiseMinAndMax MokushiNow
if flagOptMinMaxMokushi:
min, max = showMeOptMinAndMaxMokushiNow()
# Exit (only optMinMax)
if not flagSave:
IJ.log("oshimai")
raise RuntimeError("yamepi")
# Make parentDirectory
parentDir = saveDir + "postProc_" + getTimeStamp() + "_" + procTag + "/"
os.makedirs(parentDir)
# Create Table
if flagRenumFrom1:
rt = ResultsTable()
# Main Operation
procCount = 0
numberOfPage = 1
previousTitle = ""
listFiles(openDir)
# Clear ROI Manager
if flagNombre:
rm = RoiManager()
rm = RoiManager.getInstance()
rm.reset()
# Fin
finishTime = time.strftime("%Y-%m-%d %H:%M:%S")
completionTime = time.time()
IJ.log("")
IJ.log(trueTitle)
rt2 = ResultsTable()
if flagContr:
IJ.log("Contrast Adjusted by...")
IJ.log("min = " + str(min) + ", max = " + str(max))
rt2.addValue("min", min)
rt2.addValue("max", max)
if flagReso:
IJ.log("Compression Rate =" + str(compressionRate))
rt2.addValue("pre DPI", preDpi)
rt2.addValue("post DPI", postDpi)
if flagNombre:
rt2.addValue("NombreCut", "ON")
if flagSharpen:
IJ.log("Sharpen")
rt2.addValue("Sharpen", "ON")
if output == "JPEG":
IJ.log("JPEG quality = " + str(quality))
rt2.addValue("JPEG Quality", quality)
if flagRenumFrom1:
rt.show("Correspondence table")
rt.saveAs(parentDir + "Table_RenumFrom1.txt")
rt2.addValue("RenumFrom1", "ON")
rt2.saveAs(parentDir + "Settings_Log.txt")
IJ.log("")
IJ.log("Start Time .... " + startTime)
IJ.log("FinishTime ... " + finishTime)
elapsedTime = getElapsedTime(initialTime,completionTime)
IJ.log("ElapsedTime ... " + elapsedTime)
IJ.log("")
IJ.log("oshimai")
IJ.beep()
print "oshimai"
起動方法
① Fijiをダウンロード、インストール
imagej.net
② 上記プラグインをコピペして、「.pyファイル」に
Scriptを起動し、そのまま全てコピペ。
③ Fiji内「plugins」フォルダに保存
ファイル名「Almighty_Plocessing_Remake.py」と名付け、pluginsフォルダ、もしくはその配下のサブフォルダに保存。
Fiji再起動でプラグインがインストールされます。
※ 保存フォルダのPathのどこかに日本語文字を含んでいると [起動時エラー] が起きるので注意。
④ Fiji上部の「Plugins」タブから起動
起動すると処理選択画面が表示されるので、お好みの処理を。
雑記
初のJythonプログラミングでしたが、Python系の本を読んだり、Fiji Tutorialの記事やImageJ APIを読みながらで、試行錯誤しつつも楽しく作ることができました。
Macro版から翻訳するだけと思いきやアルゴリズム構造を変えなければならない部分もいくつかあったので、まともに動くようになるだけでもRPG一本やり込みクリア出来ちゃうぐらいの時間がかかった気がします。
syn.mrc-lmb.cam.ac.uk
imagej.net
最初はナニがナニやらだったのですが、APIの使い方がわかるようになると意外となんとかなる。
いままでのMacro版と同じ処理のほか、Pluginにしか出来ない+αも少しだけ実装しています。
思ったよりもいい感じに仕上がったので、「Almighty Processing」に関しては、このままこのFijiプラグインで自炊画像処理とアップデートもしていく予定です。
おしまい
ライセンスなんかは一切無いので、ぜひぜひ自由に使ってみてください!
imagej-jisui.hatenablog.com