Blit 8-bit colour to screen by converting binary values in file to 3-3-2 colour - arrays

I have recently been working on a small emulated 8-bit CPU that I wish to have graphics capabilities. At the moment, it dumps the upper 16K of ram as a binary file every cycle for it to be read as "video memory." I've made a simple pygame-based program that reads the file and then attempts to convert it to a 128x128 grayscale 3d array for it to be directly blit as a surface. It does not work. I thought I could directly cut to the chase and just ask, Is there a way to read a binary file and convert its bytes into 3-3-2 colour, regardless of the file's actual content?
Here's my current code:
import pygame
import numpy as np
from time import sleep
class Viewer:
def __init__(self, update_func, display_size):
self.display_size = display_size
self.update_func = update_func
pygame.init()
self.display = pygame.display.set_mode(display_size)
def set_title(self, title):
pygame.display.set_caption(title)
def start(self):
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
z = self.update_func()
surf = pygame.surfarray.make_surface(z)
new = pygame.transform.scale(surf, self.display_size)
self.display.blit(new, (0, 0))
pygame.display.update()
pygame.quit()
def update():
file = open("core.bin", "rb")
value = bytearray(file.read())
lst = list(value)
file.close()
image = [[ [lst for col in range(len(lst))] for col in range(len(lst))] for row in range(len(lst))]
print(image)
sleep(0.25)
return image
viewer = Viewer(update, (512, 512))
viewer.start()
update()
I've tried numpy.dstack in the past, and normal 3d arrays work fine with my code, just not binary files. And yes, my bin files are exactly 16k. No error messages either.
Not Working
My Intent

Made a 128 *128 8-bit image, for testing; assuming RRRGGGBB, as opposed to BBGGGRRR. Flip 'em around, if that's the case. Found that numpy's reshape() wrecked images. Injecting values directly into the expected numpy location gave better results. Should be faster, too.
#! /usr/bin/env python3
import pygame
import numpy as np
from time import sleep
from random import randint
class Viewer:
def __init__(self, update_func, display_size):
self.display_size = display_size
self.update_func = update_func
pygame.init()
self.display = pygame.display.set_mode(display_size)
def set_title(self, title):
pygame.display.set_caption(title)
def start(self):
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
z = self.update_func()
surf = pygame.surfarray.make_surface(z)
new = pygame.transform.scale(surf, self.display_size)
self.display.blit(new, (0, 0))
pygame.display.update()
pygame.quit()
'''
32 111 000 00 = randint( 0, 7 ) << 5 r
64 000 111 00 = randint( 0, 7 ) << 2 g
96 000 000 11 = randint( 0, 3 ) b
128 111 111 11 = randint( 0, 255 ) w
'''
screenshot = bytearray( 128 *128 ) ## 128 *128 8-bit image, just for testing
for red in range( 0, 128 *32 ): screenshot[ red ] = randint( 0, 7 ) << 5
for green in range( 128 *32, 128 *64 ): screenshot[ green ] = randint( 0, 7 ) << 2
for blue in range( 128 *64, 128 *96 ): screenshot[ blue ] = randint( 0, 3 )
for white in range( 128 *96, 128 *128 ): screenshot[ white ] = randint( 0, 255 )
row, col = 0, 0
arr = np .zeros( ( 128, 128, 3 ) ) ## generate empty numpy array
for byte in screenshot:
rrr = int( ( ( byte & 0b11100000 ) >> 5 ) *36.4285714286 ) ## red
ggg = int( ( ( byte & 0b00011100 ) >> 2 ) *36.4285714286 ) ## green
bb = int( ( byte & 0b00000011 ) *85 ) ## blue -- multiplied to max 255 range
arr[ col ][ row ][ 0 ] = rrr ## insert color values directly into numpy cells
arr[ col ][ row ][ 1 ] = ggg
arr[ col ][ row ][ 2 ] = bb
col += 1
if col == 128:
col = 0 ## \r carriage return
row += 1 ## \n newline
def update():
image = arr
sleep(0.25)
return image
viewer = Viewer(update, (512, 512))
viewer.start()
update()

Related

Element wise comparison in R

I'm attempting to write a for loop that will compare values between two individuals, but not the same individual. The following data frame contains values for five subjects:
Value1
Subject1 0
Subject2 1
Subject3 5
Subject4 6
Subject5 8
I've written a double loop that creates a 'Value2' variable based on the following criteria:
If the subject has a larger Value1, then the result is +1.
If the subject has an equal Value1, then the result is 0.
If the subject has a smaller Value1, then the result is -1.
For example, Subject 1's Value1 is smaller than the other four subjects; this should result in -4. So far the loop I've written works for the first subject but fails to iterate to the second subject.
Value2<-0
i = 0
w = 0
for(i in 1:length(Value1)){
for(j in 1:length(Value1)){
if(i != j){
Value1[i] = w
if(w > Value1[j]){
Value2[i] = Value2[i] + 1
}
if(w < Value1[j]){
Value2[i] = Value2[i] - 1
}
if(w == Value1[j]){
Value2[i] = Value2[i] + 0
}
}
}
}
If I'm understanding the problem correctly, this should give you what you want
x <- c(0, 1, 5, 6, 8)
colSums(outer(x, x, '<')) - colSums(outer(x, x, '>'))
# [1] -4 -2 0 2 4
Or
-colSums(sign(outer(x, x, '-')))
# [1] -4 -2 0 2 4
Edit: If your vector is large (or even if it isn't, really) use d.b.'s rank method instead. The outer function will create an NxN matrix where N is the length of x. For example, when x is sample(1e5) outer will attempt to create a matrix >30Gb in size! This means most people's laptops in 2019 don't even have enough memory for this method to work on large vectors. With this same x, the method using rank provided by d.b. returns the result almost instantly.
Benchmark for vector of size 1000
x <- sample(1000)
microbenchmark(
outer_diff = colSums(-sign(outer(x, x, '-'))),
outer_gtlt = colSums(outer(x, x, '<')) - colSums(outer(x, x, '>')),
rank = {r <- rank(x); 2*(r - mean(r))}
)
# Unit: microseconds
# expr min lq mean median uq max neval cld
# outer_diff 15930.26 16872.4175 20946.2980 18030.776 25346.677 38668.324 100 b
# outer_gtlt 14168.21 15120.4165 28970.7731 16698.264 23857.651 352390.298 100 b
# rank 111.18 141.5385 170.8885 177.026 188.513 282.257 100 a
x = c(0, 1, 5, 6, 8)
r = rank(x)
ans = 2 * (r - mean(r))
ans
#[1] -4 -2 0 2 4
#IceCreamToucan's benchmark considers cases with distinct values (sampling without replacement), but if we extend to repeated values (covered by criterion 2 in the OP), I figured tabulating first saves time.
library(data.table)
# from #d.b's answer and comments from d.b, ICT
fdb = function(x) {
r = frank(x)
2 * (r - mean(r))
}
# from #chinsoon's comment and some algebra
fdb2 = function(x) {
r = frank(x)
2 * r - length(x) - 1
}
# tabulation with data.table
ff = function(x){
nx = length(x)
xDT = setDT(list(x=x))
resDT = xDT[, .N, keyby=x][, res := 2L*cumsum(N) - N - nx]
resDT[xDT, x.res]
}
Sample data and results:
nv = 1e4 # number of values
n = 1e7 # length of vector
x = sample(nv, n, replace=TRUE)
system.time(res_fdb <- fdb(x))
# user system elapsed
# 0.32 0.09 0.24
system.time(res_fdb2 <- fdb2(x))
# user system elapsed
# 0.25 0.13 0.27
system.time(res_ff <- ff(x))
# user system elapsed
# 0.58 0.24 0.50
identical(res_ff, as.integer(res_fdb)) # TRUE
identical(res_ff, as.integer(res_fdb2)) # TRUE
Turns out ff() not as fast as direct use of data.table::frank, taking roughly twice as long because grouping by distinct values is done twice: once to count, and again in a lookup.
I guess the tabulation can also be done with base R's table.
ft = function(x){
nx = length(x)
N = table(x)
cN = cumsum(N)
res = 2L*cN - N - nx
as.vector(res[as.character(x)])
}
system.time(res_ft <- ft(x))
# user system elapsed
# 7.58 0.34 7.93
identical(res_ff, res_ft)
# [1] TRUE

How to make DE0-nano use ttl-232R-3V3 cable communication with PC by 1 bit(with clash-lang)?

I am trying to use the Altera DE0-nano to communication with the PC. I am using the ttl-232R-3v3 cable, currently it transmit 8 bits data once, but with the cable, it can be 1 bit a time transmit. How do I do it?
I have finish the 8 bit code:
type ST = BitVector 28
example :: ( ST , ST ) -> BitVector 8 -> (( ST , ST ) , BitVector 8)
example ( cntr1 , cntr2 ) input = ((cntr1’,cntr2’) , out)
where
sec_5 = 250000000
ascii_Y = 0x59 --ASCII for "Y" yes
ascii_N = 0x4E --ASCII for "N" no
cntr1’ | cntr1 >= sec_5 = 0 --At 50 MHz : 5 seconds
| otherwise = cntr1 + 1
cntr2’ = cntr2
out | input == maxBound = ascii_Y
| otherwise = ascii_Y
Here is the output:

Matlab - Subtract 1 vector with another in struct array

I have to different struct arrays(In the same Matlab file), what I want is to take 1 parameter/vector from a variable in a struct array and subtract it with different parameters from another variable in another struct array, is this possible?
Here is a small part of my code:
Dist(1).name = 'Pristina'
Dist(1).KM_To_Fushe_ks = 13.7 % 199-13.7 =
Dist(1).KM_to_Lipjan = 8.7 % 199-8.7 =
Dist(1).KM_to_Sllatina = 4.2 % 199-4.2 =
Dist(1).KM_to_Hajvali = 3.5 % 199-3.5 =
Dist(1).KM_to_Mitrovica = 46.9 % 199-46.9 =
Dist(1).KM_to_Anija = 1.9 % 199-1.9 =
EV(1).name = 'Nissan Leaf 24 kWh pack'
EV(1).RangeInKM_By_Manufacturer = 199 %SUBTRACT this with parameters above:
EV(1).Battery_Capacity = 21.6
EV(1).Battery_Warranty_KM = 100000
EV(1).Battery_Warrany_Year = 5
EV(1).EnginePower_Kw = 80
EV(1).EnginePower_hK = 109
EV(1).Torque_in_NewtonMeter = 254
EV(1).QuickCharging_type = 'CHAdeMO'
EV(1).QuickChargingEffect_kW_DC = 50
EV(1).NormalCharging_OnBoard_kW_AC = 3.3
EV(1).Seats = 5
EV(1).Luggage_in_Liters = 370
EV(1).Consumption_Mixed_kWh_per_10km_NEDC = 1.5
EV(1).Weight_Without_Driver = 1475
EV(1).TopSpeed_KM_per_hour = 144
EV(1).Acceleration_0to100KM_per_hour = 11.5
EV(1).RangeInKM_By_Manufacturer_RANK = 10
What I want is to have the number off 199 as a vector, and substract it by all these numbers = [13.7, 8.7, 4.2, 3.5, 46.9, 1.9]
How to do this?
Maybe I misinterpret your question, but this seem to work:
EV(1).RangeInKM_By_Manufacturer = 199 - Dist(1).KM_To_Fushe_ks
In the line you quote in your question, you left the initialization of KM_To_Fushe_ks after the difference; in short, you cannot have to vaiable assignements in the same command.
Also, if you end your lines with semi-colons you will suppress the output to the command window. Like this:
Dist(1).name = 'Pristina';
Dist(1).KM_To_Fushe_ks = 13.7;
Dist(1).KM_to_Lipjan = 8.7;
% Etc...
Here is one solution to my problem:
distances = [KM_to_Fushe_KS, KM_to_Lipjan];
remainingrange = arrayfun(#(s) s.RangeInKM - distances, EV, 'UniformOutput', false)
Or I could do this:
remainingrange = cell(size(EV));
for evidx = 1:numel(EV)
remaingrange{evidx} = EV(evidx).RangeInKM - distances;
end
Another solution is doing is putting multiple distances in once matrix:
Example:
Towns = {'Town1', 'Town2', 'Town3', 'Town4'};
distances = [0 200 13.7 8.7;
200 0 13.3 9.3;
13.7 13.3 0 255;
8.7 9.3 255 0];
EVs = {'Nissan Leaf 24 kWh pack', 'Nissan Leaf 30 kWh pack'};
ranges = [199 250];
And then I can calculate distances as a 3D matrix:
remainingrange = permute(ranges, [1 3 2]) - distances;
remainingrange = bsxfun(#minus, permute(ranges, [1 3 2]), distances);
If I want to check if a EV has not enough range in KM, I could write:
tooFarForMyEV = find(remainingrange < 0)
[from, to, ev] = ind2sub(size(remainingrange), tooFarForMyEV);
lackingrange = table(Towns(from)', Towns(to)', EVs(ev)', remainingrange(tooFarForMyEV), 'VariableNames', {'From', 'To', 'EV', 'Deficit'})

Assigning a tuple from a dictionary to an array Python

I have a pivot table array with factors and X and Y coordinates such as the one below, and I have a look up table with 64 colours that have RGB values. I have assigned a colour to each factor combination using a dictionary of tuples, but I am having a hard time figuring out how to now compare the keys of my dictonary (which are the different combination of factors) to my array so that each row that has that factor combination can be assigned the colour given in the dictionary.
This is an example of the Pivot Table:
A B C D Xpoint Ypoint
0 1 0 0 20 20
0 1 1 0 30 30
0 1 0 0 40 40
1 0 1 0 50 50
1 0 1 0 60 60
EDIT: This is an example of the LUT:
R G B
0 0 0
1 0 103
0 21 68
95 173 58
and this is an example of the dictionary that was made:
{
(0, 1, 0, 0): (1, 0, 103),
(0, 1, 1, 0): (12, 76, 161),
(1, 0, 1, 0): (0, 0, 0)
}
This is the code that I have used:
import numpy as np
from PIL import Image, ImageDraw
## load in LUT of 64 colours ##
LUT = np.loadtxt('LUT64.csv', skiprows=1, delimiter=',')
print LUT
## load in XY COordinates ##
PivotTable = np.loadtxt('PivotTable_2017-07-13_001.txt', skiprows=1, delimiter='\t')
print PivotTable
## Bring in image ##
IM = Image.open("mothTest.tif")
#bring in number of factors
numFactors = 4
#assign colour vectors to factor combos
iterColours = iter(LUT)
colour_dict = dict() # size will tell you how many colours will be used
for entry in PivotTable:
key = tuple(entry[0:numBiomarkers])
if key not in colour_dict:
colour_dict[key] = next(iterColours)
print(colour_dict)
Is there a way to compare the tuples in this dictionary to the rows in the pivot table array, or maybe there is a better way of doing this? Any help would be greatly appreciated!
If your target is, as I suppose in my comment above, to trace back the colors to the ntuple, then you already did everything. But I do not catch which role is played by the tif file ... Please note I corrected the reference to the non-existent NumBiomarkers variable...
import numpy as np
from PIL import Image, ImageDraw
## load in LUT of 64 colours ##
LUT = np.loadtxt('LUT64.csv', skiprows=1, delimiter=',')
print LUT
## load in XY COordinates ##
PivotTable = np.loadtxt('PivotTable_2017-07-13_001.txt', skiprows=1, delimiter=',')
print PivotTable
## Bring in image ##
IM = Image.open("Lenna.tif")
#bring in number of factors
numFactors = 4
#assign colour vectors to factor combos
iterColours = iter(LUT)
colour_dict = dict() # size will tell you how many colours will be used
for entry in PivotTable:
key = tuple(entry[0:numFactors])
if key not in colour_dict:
colour_dict[key] = next(iterColours)
print(colour_dict)
print '===='
for entry in PivotTable:
key = tuple(entry[0:numFactors])
print str(entry) + ' ' + str(colour_dict[key])
can you please add a short example for LUT64.csv, for PivotTable_2017-07-13_001.txt ? Maybe for this one you should also use a different delimiter than \t to ensure portability of your examples.
Regards

How to assign values to image in matlab

I have 5 columns x, y, r, g, b with values of line number, column number, red, green and blue. The lines of this n by 5 matrix are not in a particular order, however they are consistent with image(x,y) and the r,g,b.
I would like to do something like I=uint8(zeros(480,640,3) and just change those rgb values based on the n by 5 mat.
Something along the lines of I(mat(:,1), mat(:,2), 1)=mat(:,3) for red etc
The following uses the concept of linear indexing and the versatile bsxfun function:
m = 640; %// number of rows
n = 480; %// number of columns
I = zeros(m, n, 3, 'uint8'); %// initiallize directly as uint8
I(bsxfun(#plus, x(:)+(y(:)-1)*m, (0:2)*m*n)) = [r(:) g(:) b(:)]; %// fill values
Small example: for
m = 2;
n = 3;
x = [1 2 1];
y = [1 1 2];
r = [ 1 2 3];
g = [11 12 13];
b = [21 22 23];
the code produces
I(:,:,1) =
1 3 0
2 0 0
I(:,:,2) =
11 13 0
12 0 0
I(:,:,3) =
21 23 0
22 0 0
An alternative:
INDr = sub2ind([480, 640, 3], mat(:, 1), mat(:,2), ones([numel(mat(:,3)), 1]));
INDg = sub2ind([480, 640, 3], mat(:, 1), mat(:,2), 2*ones([numel(mat(:,3)), 1]));
INDb = sub2ind([480, 640, 3], mat(:, 1), mat(:,2), 3*ones([numel(mat(:,3)), 1]));
I=uint8(zeros(480,640, 3));
I(INDr)=mat(:,3);
I(INDg)=mat(:,4);
I(INDb)=mat(:,5);
Note that in Matlab, the convention between axes is different between images and arrays.

Resources