その漫画自炊オタクはImageJマクロに恋をする

プログラミングを用いた、自炊漫画の画像処理

【Fiji・Jython】2024リメイクPluginバージョン 自炊画像処理はこれひとつ!

 

 


  

自炊でいちばんよく使う多目的Macroを、FijiのJython(Python)を用いてPluginにリメイクしました。ちょこっと新機能付き。

 

 

 

※ 2024/02/25 追記. いろいろアップデートしていましたが、ver 10.13.2でいちおう暫定的に完成です。余計な処理を省いたので、Autoの最適コントラスト値探査 (optMinMaxAuto) が爆速になりました。

 

 

 

旧マクロバージョン

imagej-jisui.hatenablog.com

 

 

もくじ

 

 

Jython コード

# 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