The problem I need to face right now is that I have a certain amount of bytearrays with different sizes. I want to put them into one single bytearray that is way larger than all the other bytearrays together so that voids occur inside of this large bytearray where no bytes have been put in.
The bytearrays are distributed randomly over the large bytearray but no bytearray may collide with another bytearray that has already been put there.
Is there an efficient why to do this random distribution without collisions?
With the following function:
from random import randint, shuffle
import itertools
import operator
def random_distribution(image, files):
shuffle(files)
available_size = len(image) - sum(map(len, files))
gap_positions = sorted([randint(0, available_size) for i in range(len(files))])
gap_deltas = itertools.starmap(operator.sub, zip(gap_positions, [0] + gap_positions))
position = 0
for file, gap_delta in zip(files, gap_deltas):
position += gap_delta
image[position : position + len(file)] = file
position += len(file)
return image
We randomly distribute 3 files into an image of 20 bytes for 10 times:
>>> files = ['abc', '1234', 'ABCDE']
>>> for i in range(10):
... print(random_distribution(bytearray(20), files).replace('\x00', '.'))
...
.abc.1234...ABCDE...
..ABCDE.abc....1234.
abcABCDE......1234..
..1234...ABCDE...abc
..1234.....abc.ABCDE
...abc.1234..ABCDE..
abc...ABCDE....1234.
.ABCDE..abc1234.....
....ABCDE..1234.abc.
1234..ABCDE.abc.....
The idea is to first calculate the free space by subtracting the total size of the files from the size of the image, and then randomly slice up the free space by picking random positions within the free space (which I call "gap positions"). The deltas between the gap positions will become the gaps between the files, so when we copy the files into the image, we skip the corresponding gap delta before we place a file behind the end of the last file.
Related
I am trying to figure out how to load a PNG image and create a matrix containing the RGB values of each pixel. I am currently using the following method to load the file and get the various RGB values:
def to_pixels
File.open(#file, 'r') do |file|
byte_block = file.read
byte_block.each_byte do |byte|
#pixels << byte
end
end
end
From my understanding, each pixel contains 3-bytes representing the R,G, and B value. I initially tried taking the output array #pixels and grouping into sub-groups of 3 elements assuming that the pixel order and RGB value of each pixel was preserved in my output. E.g.:
#pixels = #pixels.each_slice(3).to_a
The length of the array that I created was nearly the same length as the total number of pixels in my original image, so I was encouraged. However, I used ChunkyPNG to take my RGB pixel array and print back to an image, and it looks like random color noise. Could some of the bytes being input into #pixels represent metadata? Or perhaps would the bytes being output not be ordered as R,G, then B values of individual pictures, but perhaps all the R bytes, then all the G bytes, then all the B bytes for example?
I would like to figure out how to transform the byte array into an array of arrays grouping RGB values of the image in some logical order (start at top left and work across to the right, or start in top left and work down, etc)
The chunky_png gem can do this. https://github.com/wvanbergen/chunky_png
Something like:
img = ChunkyPNG::Image.from_file(#file)
img.pixels.each do |pixel|
puts ChunkyPNG::Color.to_hex(pixel) # would spit out a hex string like "#b8e1f6ff"
end
There are a number of other methods if you want different formats: to_grayscale, to_grayscale_alpha_bytes, to_grayscale_bytes, to_hex, to_hsb, to_hsl, to_hsv, to_s, to_truecolor_alpha_bytes, to_truecolor_bytes.
I have an array which stores the information of a 20x20 black and white image.
int array[][] = new int[20][20];
If the pixel is black at a specific point, for example (0,5) I insert the value one into my array.
array[0][5] = 1;
I am trying to create a dataset so I can feed it into a neural network. I was wondering if there is a way to reduce the size of input values (20x20 = 400) by compressing the information.
I have these series of 2D CT images and i have been able to read them into Matlab using "imread". The issue however is that i need the image read-in as a single 3D matrix rather than stack of several 2D matrices. I have been made aware that it is possible to store the number of 2D layers as the 3rd dimension, but i have no idea how to do this as i am still a learner.
The code i have for reading in the 2D stack are as follows:
a = dir('*.tif');
for i = 1: numel(a)
b = imread(a(i).name); %read in the image
b_threshold = graythresh(b); %apply threshold
b_binary = im2bw(b, b_threshold); %binarize image
[m, n] = size(b); %compute the size of the matrix
phi(i) = ((m*n) - sum((b_binary(:))))/(m*n); %compute the fraction of pore pixels in the image
phi(:,i) = phi(i); %store each of the above result
end
I have added just a single image although several of these are needed. Nevertheless, one can easily duplicate the image to create a stack of 2D images. For the code to work, it is however important to rename them in a numerical order.pore_image
Any help/suggestions/ideas is welcomed. Thanks!
You can simply assign along the third dimension using i as your index
stack_of_images(:,:,i) = b_binary
Well, the first advice is try to don't use the variable i and j in matlab because they are reserved (have a look here and here).
After it depends on along which dimension you want to store the 2D images:
if you want to store the images along the first dimension just use this code:
a = dir('*.tif');
for ii = 1: numel(a)
b = imread(a(ii).name); %read in the image
b_threshold = graythresh(b); %apply threshold
b_binary = im2bw(b, b_threshold); %binarize image
[m, n] = size(b); %compute the size of the matrix
phi(ii) = ((m*n) - sum((b_binary(:))))/(m*n); %compute the fraction of pore pixels in the image
phi(:,ii) = phi(ii); %store each of the above result
matrix_3D_images(ii,:,:)=b_binary; %adding a new layer
end
If you want to store the images along other dimensions it is easy to do: just change the posizion of the "pointer" ii:
matrix_3D_images(:,ii,:)=b_binary; or
matrix_3D_images(:,:,ii)=b_binary;
I have a code to crop connected components of input image, input, by finding the boundary conditions from a binary image's labelled map, labelledmap ([labelledmap, labelcount] = bwlabel(hvedged, 8);)
I'm new to matlab so this might sound stupid..
The problem is, I am unable to store different cropped images in the same variable, Because matlab seems to merge the ends of the already existing image and the new cropped image, i.e, it is storing the complete map between the two cropped images, the way i see it :/
This is the output Using different variables for storing cropped image (the kind of output i want)
Output Using different variables for storing cropped image
This is the output i'm getting by storing the cropped image in the same variable(not helpful)
Output when storing cropped image in the same varible
I tried using an array of size equal to total number of labels produced but it's giving the same result.. also i tried clearvars for clearing the output token image, ltoken, after every iteration of the loop but it's not helping
So, is there any possible way to display individual cropped images.. also the number of cropped images might be in thousands so i want to use a loop to code their cropping mechanism
here is a part of the code attached.. thanks in advance ;)
for h=1:labelcount
for i=1:r
for j=1:c
if labelledmap(i,j)==h
if i<ltop
ltop=i;
end
if i>lbottom
lbottom=i;
end
if j<lleft
lleft=j;
end
if j>lright
lright=j;
end
end
end
end
if ltop>5
ltop=ltop-5;
end
if lbottom<r-5
lbottom=lbottom+5;
end
if lleft>5
lleft=lleft-5;
end
if lright<c-5
lright=lright+5;
end
lwidth=lright-lleft;
lheight=lbottom-ltop;
ltoken=imcrop(input,[lleft ltop lwidth lheight]);
figure('Name', 'Cropped Token'), imshow(ltoken);
clearvars ltoken;
end
you need to initialize ltop lbottom lleft and lright for each iteration of label h. I think this is the reason why you get the cropped images "glued" together.
It is EXTREMELY inefficient to go through all the pixels for each and every one of your labels. Especially when you are expected to have many labels.
Use regionprops to get the 'BoundingBox' property for each label.
Here's an example
st = regionprops( labelledmap, 'BoundingBox' );
imlist = cell( 1, numel(st) ); % pre-allocate
for ii=1:numel(st)
r = st(ii).BoundingBox;
% I understand you want to increase the BB by 5 pixels at each side:
r(1:2) = r(1:2) - 5; % start point moves -5
r(3:4) = r(3:4) + 10; % width and height increases by 10
imlist{ii} = imcrop( input, r );
end
I'm still a bit in shock by your code that explicitly loops through all pixels just for finding the bouding box. This is NOT the matlab way of doing things.
If you insist on NOT using regionprops here's a more Matlab-ish way of finding the ii-th bounding box:
imsk = (labeledmap == ii); % create a binary map with True for ii-th region
xFlat = any(imsk,1); % "flattening" imsk on the x-axis
lleft = find( xFlat, 1, 'first' );
lright = find( xFlat, 1, 'last' );
yFlat = any(imsk, 2);
ltop = find( yFlat, 1, 'first' );
lbottom = find( yFlat, 1, 'last' );
No loops at all over image coordinates.
I need to create a 1-D array of 2-D arrays, so that a program can read each 2-D array separately.
I have a large array with 5 columns, with the second column storing 'marker' data. Depending on the marker value, I need to take the corresponding data from the remaining 4 columns and put them into a new array on its own.
I was thinking of having two for loops running, one to take the target data and write it to a cell in the 1-D array, and one to read the initial array line-by-line, looking for the markers.
I feel like this is a fairly simple issue, I'm just having trouble figuring out how to essentially cut and paste certain parts of an array and write them to a new one.
Thanks in advance.
No for loops needed, use your marker with logical indexing. For example, if your large array is A :
B=A(A(:,2)==marker,[1 3:5])
will select all rows where the marker was present, without the 2nd col. Then you can use reshape or the (:) operator to make it 1D, for example
B=B(:)
or, if you want a one-liner:
B=reshape(A(A(:,2)==marker,[1 3:5]),1,[]);
I am just answering my own question to show any potential future users the solution I came up with eventually.
%=======SPECIFY CSV INPUT FILE HERE========
MARKER_DATA=csvread('ESphnB2.csv'); % load data from csv file
%===================================
A=MARKER_DATA(:,2); % create 1D array for markers
A=A'; % make column into row
for i=1:length(A) % for every marker
if A(i) ~= 231 % if it is not 231 then
A(i)=0; % set value to zero
end
end
edgeArray = diff([0; (A(:) ~= 0); 0]); % set non-zero values to 1
ind = [find(edgeArray > 0) find(edgeArray < 0)-1]; % find indices of 1 and save to array with beginning and end
t=1; % initialize counter for trials
for j=1:size(ind,1) % for every marked index
B{t}=MARKER_DATA(ind(j,1):ind(j,2),[3:6]); % create an array with the rows from the data according to indicies
t=t+1; % create a new trial
end
gazeVectors=B'; % reorient and rename array of trials for saccade analysis
%======SPECIFY MAT OUTPUT FILE HERE===
save('Trial_Data_2.mat','gazeVectors'); % save array to mat file
%=====================================