Seite 1 von 1

Restbits in Array-Spalten zufällig aufteilen

Verfasst: Samstag 6. Juli 2019, 17:42
von Erhy
Hallo!
Als Autodidakt zweifle ich, ob der Code effizient ist.
Bin für Kommentare zum unterstehenden Code dankbar

Erhy

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
import imageio

filReadPathImage = r'C:\Users\gle\AppData\Local\Temp\DistDepMod\DispDepMod_2019-7-3_21_14_53.bmp'
picdata = np.asarray( imageio.imread(filReadPathImage)[:,:,:3] )  #not with transparency channel
picShape = picdata.shape
factpreci = 1 / 255.0
picw = picdata * factpreci #picw in range 0...1.0
#
# some calculations
# e.g.
refcolor = picw[ 0, 0 ]
picCalc = np.zeros_like(picw[:,:,0])
for colix in range(0, 3):
	picCalc[:,:] += np.fabs( ( refcolor[colix] - picw[:,:,colix] ) )
# calculation done

# finishing of the modified image

arrInt = (np.clip( picCalc, 0.0 , 3.0) / factpreci ).astype(np.int)

picFinished = np.ma.empty_like(picdata) #so it is uint8

picModQuot, picModRema = np.divmod(arrInt, 3 )

picFinished[:,:,0] = picFinished[:,:,1] = picFinished[:,:,2] = picModQuot
#
# distribute the remainder randomly to avoid moiré
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# perhaps this can be coded in a smarter way:
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
picRandsIxsFi = np.random.randint(3, size=(picShape[0] * picShape[1]))
picRandsIxsFirst = picRandsIxsFi.reshape((picShape[0], picShape[1]))
# picRandsIxsFirst: values from 0 to 2

#pseudo random:
picRandsRotateAmount = picRandsIxsFi[-1::-1].reshape((picShape[0], picShape[1]))

twoPartsToAdd = np.array([[0,0],[1,0],[1,1]], dtype=np.uint8 )	# remainder with 0..2 is able to access the parts
rotatedIxs = np.array([[1,2],[2,0],[0,1]])			# rotation of indices 0,1,2 by 1, and by 2
			
for i in np.ndindex(picShape[0],picShape[1]):
	r = picModRema[i[0],i[1]] #remainder
	if r != 0 :
		tLow = twoPartsToAdd[r,0] # the low significant remainder
		if tLow != 0 :
			colorIx = picRandsIxsFirst[i[0],i[1]]
			picFinished[ i[0], i[1], colorIx ]	+= tLow

		tHigh = twoPartsToAdd[r,1] # the high significant remainder
		if tHigh  != 0 :
			rotAmount = picRandsRotateAmount[i[0],i[1]] // 2 #  is not really random
			rotIx = rotatedIxs[colorIx, rotAmount ]
			picFinished[ i[0], i[1], rotIx ] += tHigh
#
# now result image picFinished was built
#
plt.imshow(picFinished)
plt.show()



Re: Restbits in Array-Spalten zufällig aufteilen

Verfasst: Dienstag 9. Juli 2019, 15:37
von Erhy
nun der Code, welcher um mehr als 800 mal schneller zum Resultat führt

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
import imageio

filReadPathImage = r'C:\Users\gle\AppData\Local\Temp\DistDepMod\DispDepMod_2019-7-9_16_00_19.bmp'
picdata = np.asarray( imageio.imread(filReadPathImage)[:,:,:3] )  #not with transparency channel
picShape = picdata.shape
maxValPerColor = 255
picw = picdata / maxValPerColor #picw in range 0...1.0
#
# some calculations
# e.g.
refcolor = picw[ 0, 0 ]
picCalc = np.zeros_like(picw[:,:,0])
for colix in range(0, 3):
	picCalc[:,:] += np.fabs( ( refcolor[colix] - picw[:,:,colix] ) )
# calculation done

# finishing of the image with the modifications
picCalcFlat = picCalc.reshape(picShape[0] * picShape[1]) #flat array, because it is faster to work with
arrInt = (np.clip( picCalcFlat, 0.0 , 3.0) * maxValPerColor ).astype(np.int)
picFinishFlat = np.empty((picShape[0] * picShape[1], picShape[2]), dtype=np.uint8)
picModQuot, picModRema = np.divmod(arrInt, 3 )
picFinishFlat[:,0] = picFinishFlat[:,1] = picFinishFlat[:,2] = picModQuot
#picFinishFlat[:,:] = np.expand_dims(picModQuot,axis=1) # slower as above
#
# distribute the remainder randomly to avoid moiré
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# in a smarter way:
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
picRandsIxsFirst = np.random.randint(3, size=(picShape[0] * picShape[1]), dtype=np.uint8 )
# picRandsIxsFirst: values from 0 to 2
picRandsRotateAmount = picRandsIxsFirst[-1::-1] #reverse random
# picRandsRotateAmount: also values from 0 to 2
twoPartsToAdd = np.array([[0,0],[1,0],[1,1]], dtype=np.uint8 ) # remainder parts
rotatedIxs = np.array([[1,2],[2,0],[0,1]]) # rotation of indices 0,1,2 by 1 or 2
			
restToAddArr = np.bitwise_or( \
	np.left_shift( twoPartsToAdd[picModRema[:],0] , picRandsIxsFirst[:] ),
	np.left_shift( twoPartsToAdd[picModRema[:],1] ,
						rotatedIxs[ picRandsIxsFirst[:], picRandsRotateAmount[:] // 2 ] ) )
				
picFinishFlat[:,0] += (np.bitwise_and(restToAddArr,1)).astype(bool)
picFinishFlat[:,1] += (np.bitwise_and(restToAddArr,2)).astype(bool)
picFinishFlat[:,2] += (np.bitwise_and(restToAddArr,4)).astype(bool)

picFinished = picFinishFlat.reshape(picShape[0], picShape[1], picShape[2])
#
# now result image picFinished was built
#
plt.imshow(picFinished)
plt.show()

Re: Restbits in Array-Spalten zufällig aufteilen

Verfasst: Freitag 12. Juli 2019, 17:28
von ggamauf
dieser code dokumentiert bildkordinaten?

Re: Restbits in Array-Spalten zufällig aufteilen

Verfasst: Freitag 12. Juli 2019, 20:28
von Erhy
in dem Code wird ein Graubild, als Gleitkomma-Array, auf die Farbkomponenten rgb aufgeteilt.
Da bei der Divisionen der Grauwerte durch 3 Reste verbleiben,
werden diese Restbits random auf die 3 Kanäle aufgeteilt,
was mir anfangs Schwierigkeiten bereitet hat.