how to load np.array from text file using np.genfromtxt - python-3.x

The file has the following structure:
h
w
P1,1_r P1,1_g P1,1_b
P1,2_r P1,2_g P1,2_b
...
P1,w_r P1,w_g P1,w_b
P2,1_r P2,1_g P2,1_b
...
Ph,w_r Ph,w_g Ph,w_b
The first line contains one integer, h, which is the height of the image. The second line contains one integer, w, which is the width of the image. The next h x w lines contain the pixel value as a list of three values corresponding to red, green, and blue color of the pixel. The list of pixels are arranged in the top-to-bottom then left-to-right order.
How can convert this to a np.array using np.genfromtxt?

If you want to read in the data from a .txt file as a numpy array, you need to first read the file data in, then use np.genfromtext on the resulting object:
file = open("filename.txt")
#separate the first two lines containing h and w
hw = file.readlines(2)
# get h and w, as integers from hw by indexing them by line numbers
h = int(hw[0])
w = int(hw[1])
This leaves the rest of file containing the np.array with the image data in. Use np.genfromtxt on this:
figure = np.genfromtxt(file)

Related

Detecting consecutive k points in data, which are out of specification limit - Python3

I want to create an SPC chart that will detect data points that are out of specification limits using python.
I have a data set that contains column [XX] which is the one that I'd like to test and DateTime type data as an index.
I have already come up with an idea of how to detect points that are out of spec, and points that more than k points in a row are out of spec limit. On the other hand, I assume that there has to be a better way to achieve the same outcome. Below you find my code.
`# first part to detect points that are out of spec
import plotly.graph_objects as go
# creat a upper and lower spec limit (that are used to plot a line on an SPC chart)
df['USL_MarginesG'] = 5.5
df['LSL_MarginesG'] = 3
# create empty list to contain data points that are out of spec
occ_trace_x = []
occ_trace_y =[]
# for all elements in df['XX'] I look for elements that are out of spec and append them to the created list
for y in range(len(df['XX'])):
if df['XX'].iloc[y] > 5.5 or df['XX'].iloc[y] < 3:
occ_trace_x.append(df.index[y])
occ_trace_y.append(df['XX'].iloc[y])`
The second part of the code (this part detects k points in a row that are out of spec):
`# create containers for detected data points
list_k = []
list_index = []
# input for user to write a number for k points to detect
k = int(input("Put a number"))
# for data points in df['XX'] test if a slice from [x:x+k+1] is greather/lower that the spec.
for x in range (len(df['XX'])):
if (all(df['XX'].iloc[x:x+k+1] > 5.5) or all(df['XX'].iloc[x:x+k+1] < 3)):
if True:
# take a slice from df and convert it to a list with the aim to append the lists to created containers.
s = df['XX'].iloc[x:x+k+1].to_list()
s_index = df.index[x:x+k+1].to_list()
list_k.append(s)
list_index.append(s_index)`
The next step is to unpack the nested list:
c = []
for x in list_k:
c = c + x
v = []
for b in list_index:
v = v + b`
Last step is to plot data set on a chart:
fig = go.Figure()
fig.add_trace(go.Scatter(x=df.index, y=df['XX'],
mode='lines',
name='Margines_Górny'))
fig.add_trace(go.Scatter(
x= occ_trace_x,
y= occ_trace_y,
name= "Out of Control",
mode= "markers",
marker= dict(color="rgba(210, 77, 87, 0.7)", symbol="square", size=4)))
fig.add_trace(go.Scatter(
x = v,
y = c,
name = f'{k}' + ' parameters in a row are out of control',
mode = "markers",
marker= dict(color="yellow", symbol="square", size=4)))
fig.show()`
As a result, I got a plot with data:
blue line describes the data set
red squares detect data points out of spec
yellow squares detect k data points in a row that are out of spec k
= 2
I am looking for optimization of the code (some way that I might achieve the same results in the faster way)

MATLAB: Plotting only ponts with colorbar based on another variable

I want to plot only data points. Now I can plot the points which only considers 1 type of point. But my data contains different column variables. I want to plot different figures with different x and y variables from the data. Suppose I want to plot variable D against variable A or variable E against variable year but I want to plot data points with different colors or different types of points either *, dot, diamond etc. based on suppose, variable pub or variable E. Now for colormap I want to show colormap beside the figure with where the range of the variable value will be shown. For different type of points the point indexes will be suppose another variable E.
Also the 1st data should have a completely different point so that it can be distinguishable. My code actually shows different point for that data but it also plots with others.
Here is the truncated data.
Can anyone help me with that?
My code:
T = readtable('Data.xlsx');
year = T.Year;
pub = T.Publication;
A = T.A;
B = T.B;
C = T.C;
D = T.D;
E = T.F;
% Plot Data
f = figure;
%hold on; grid on, box on;
plot(A, D,'*')
hold on;
plot(A(1), D(1),'d')
It feels like this matlab example should be pretty close to what you want. It is a scatter plot (like your plot(A,D,'*') command), and has a colour scale that varies with a third variable c.
You should then combine this with a hold on command and plotting the first point using a different style suitable to your liking. You could something along the lines of the following (I have not downloaded your data, so I will use the example from the matlab link I provided):
x = linspace(0,3*pi,200); % Independent variable
y = cos(x) + rand(1,200); % Dependent variable
c = linspace(1,10,length(x)); % Colour variable
% Plot all points except the first one using colours in c and size 50:
scatter( x(2:end), y(2:end), 50, c(2:end) );
hold on
% Plot first point differently: twice the size, and with a filled marker:
scatter( x(1), y(1), 100, c(1), 'filled');
legend({'Data','First point'});
hold off

liblas: how to get color of a point cloud's point in las format

I'm using liblas to read a point cloud in las format:
f = file.File(pc_file_path, mode = 'r')
Then I do a for loop on points and I retrieve the color for each point with the following code:
for p in f:
c = p.color
print(c.red, c.green, c.blue)
In the print I obtain values with five digits (e.g.: 31232, 26112, 22016) while I expect to find values in the range (0, 250) for each component. What is the scale factor? I've tried with f.header.get_scale() but it doesn't resolve the problem.
Solved multiplying for 256/65535 each color component because the maximum color value is 65535.

Partitioning images based on their white space

I have lots of images of three objects with a white background separated by white space. For example,
Is it possible to split this image (and ones like it) into three images automatically? It would be great if this also worked from the command line.
As #ypnos said, you want to collapse the rows by summation, or averaging. That will leave you with a vector the width of the image. Next clip everything below a high threshold, remembering that high numbers correspond to high brightness. This will select the white space:
Then you simply cluster the remaining indices and select the middle two clusters (since the outer two belong to the bordering white space). In python this looks like so:
import sklearn.cluster, PIL.Image, numpy, sys, os.path
# import matplotlib.pyplot as plt
def split(fn, thresh=200):
img = PIL.Image.open(fn)
dat = numpy.array(img.convert(mode='L'))
h, w = dat.shape
dat = dat.mean(axis=0)
# plt.plot(dat*(dat>thresh);
path, fname = os.path.split(fn)
fname = os.path.basename(fn)
base, ext = os.path.splitext(fname)
guesses = numpy.matrix(numpy.linspace(0, len(dat), 4)).T
km = sklearn.cluster.KMeans(n_clusters=2, init=guesses)
km.fit(numpy.matrix(numpy.nonzero(dat>thresh)).T)
c1, c2 = map(int, km.cluster_centers_[[1,2]])
img.crop((0, 0, c1, h)).save(path + '/' + base + '_1' + ext)
img.crop((c1, 0, c2, h)).save(path + '/' + base + '_2' + ext)
img.crop((c2, 0, w, h)).save(path + '/' + base + '_3' + ext)
if __name__ == "__main__":
split(sys.argv[1], int(sys.argv[2]))
One shortcoming of this method is that it may stumble on images with bright objects (failing to properly identify the white space), or are not separated by a clean vertical line (e.g., overlapping in the composite). In such cases line detection, which is not constrained to vertical lines, would work better. I leave implementing that to someone else.
You need to sum-up over every column in the image and compare the sum with the theoretical sum of all pixels in that column being white (i.e., #lines times 255). Add all columns that match the criterion to a list of indices. In case there is not always a fully clean line between the objects (e.g. due to compression artifacts), you can set a lower threshold instead of the full-white sum.
Now go through your list of indices. Remove all adjacent indices that start at the first column. Also remove all adjacent indices that end at the far right of the image. Create groups of indices that are adjacent to each other. In each group count the number of indices and calculate the mean index.
Now take the two largest groups and take their mean is the index for where to crop.
You can do this in a rather small script in Python with OpenCV, or C++ OpenCV program.

Pygame blitting only updated surfaces

Right now I have an x by y array to hold integers that decide which tile to draw to the screen. (The integers choose which tile in my tile_arr to blit)
For better performance, I only want the ints that changed to be blit'ed again.
EXAMPLE 1:
For example right now I have something like:
tile_arr = [image1,image2,image3,image4]
arr = [[2,2,2],[2,2,2],[2,2,2]]
Then depending on what the user does, some values in arr might change, so lets say:
arr[0][0]=1
arr[2][1]=1
Which would give us the array:
arr=[[1,2,2],[2,2,2],[2,1,2]]
now when blitting to the screen, I would blit images from the tile_arr: image numbers 1,2,2 to the top row, 2,2,2, to the middle row, and 2,1,2 to the bottom row. When I blit the array, I use a screen.blit for each value or arr, that's nine blits. I would rather only do two blits. (Use screen.blit only twice)
EXAMPLE 2:
tile_arr = [green.bmp, red.bemp, blue.bmp]
feild_arr = [[0,0,0], [0,0,0], [0,0,0]]
Output:
G G G
G G G
G G G
User changes feild_arr to [[1,0,1], [0,2,0], [0,1,2]]
Output:
R G R
G B G
G R B
Now I only want to call sceen.blit() 5 times, leaving the 4 Green sqaures green, because nothing changed.
I thought of making another array, which would be just a copy of the first. Then run through it and compare to the new array to see what changed, but I think there is a better and faster way to this. Now the example is only 3x3 so making a duplicate array isn't too bad, but I'm working with a lot bigger arrays, and when you're blitting a 30x20 array, I need all the shortcuts I can get.
How do I only blit when the interger values in an array have been changed, and skip (don't blit) the values that have not changed?
You can use screen.blit only once, calling with a list of the rectangles that changed.
I think the best aproach is to create you own class deriving from DirtySprite:
class Cell: pygame.sprite.DirtySprite
which already has attributes for holding an image and a rectangle and you can add an attributes to hold the number and a method to change de number that will set it as dirty.
Then you can use LayeredDirty class to render the dirty sprites on the screen.

Resources