How to find the white pixel coordinates on Vivado HLS? - vivado

I have a B&W image filled with white pixels (255). How can I obtain all the white pixel coordinates present in the image on Vivado HLS?
I'm using hls::Mat to store images.
Here's my top-level function on Vivado HLS:
#include "top.h"
#include <iostream>
void dust_detect(AXI_STREAM& input_data, AXI_STREAM& output_data, int m, int n)
{
auto int pixel;
#pragma HLS DATAFLOW
//Create AXI streaming interfaces for the core
#pragma HLS INTERFACE axis port=input_data
#pragma HLS INTERFACE axis port=output_data
#pragma HLS INTERFACE ap_ctrl_none port=return
/************* Arrays used ***************/
gray_IMAGE img_0;
#pragma HLS STREAM variable=img_0
gray_IMAGE img_1;
#pragma HLS STREAM variable=img_1
gray_IMAGE img_2;
#pragma HLS STREAM variable=img_2
gray_IMAGE img_2a;
#pragma HLS STREAM variable=img_2a
gray_IMAGE img_2b;
#pragma HLS STREAM variable=img_2b
gray_IMAGE img_3;
#pragma HLS STREAM variable=img_3
gray_IMAGE img_4;
#pragma HLS STREAM variable=img_4
gray_IMAGE img_5;
#pragma HLS STREAM variable=img_5
gray_IMAGE img_6;
#pragma HLS STREAM variable=img_6
gray_IMAGE img_7;
#pragma HLS STREAM variable=img_7
gray_IMAGE img_7a;
#pragma HLS STREAM variable=img_7a
gray_IMAGE img_7b;
#pragma HLS STREAM variable=img_7b
const char coefficients1[7][10] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };
hls::Window<7,10,char> erodewindow;
for (int i=0;i<7;i++){
for (int j=0;j<10;j++){
erodewindow.val[i][j]=coefficients1[i][j];
}
}
const char coefficients2[9][12] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };
hls::Window<9,12,char> dilatewindow;
for (int i=0;i<9;i++){
for (int j=0;j<12;j++){
dilatewindow.val[i][j]=coefficients2[i][j];
}
}
hls::AXIvideo2Mat(input_data, img_0);
hls::Threshold(img_0,img_1,80,255,HLS_THRESH_BINARY);//OTSU THRESHOLDING
hls::Threshold(img_1,img_2,80,255,HLS_THRESH_BINARY_INV);//Invert the Thresholded output
hls::Duplicate(img_2,img_2a,img_2b);
hls::Erode<4,4>(img_2a,img_3,erodewindow);
hls::Dilate<6,6>(img_3,img_4,dilatewindow);
hls::Threshold(img_4,img_5,100,255,HLS_THRESH_BINARY_INV);//Invert the Dilated output
hls::Threshold(img_5,img_6,100,1,HLS_THRESH_BINARY);
hls::Mul(img_2b,img_6,img_7);
hls::Duplicate(img_7,img_7a,img_7b);
for(m=0; m<MAX_HEIGHT; m++) {
for(n=0; n<MAX_WIDTH; n++) {
#pragma HLS PIPELINE IT=1
auto pixel = img_7a.read();
if(pixel != 0)
{
printf("White pixel found at x: " + m + "\ty: " + n) ; // White pixel found at (x,y)
}
}
}
hls::Mat2AXIvideo(img_7b,output_data);
}
I need help with the part of the code after hls::Mul that's used to find the white pixel coordinates in image img_7a.

The question is fairly broad, as there can be many ways to achieve you're goal depending on your setup and requirements.
However, if you're using an hls::Mat type for storing your image, the actual image is stored into a FIFO. So for identifying all the white pixels, you would be forced to scan all the pixels of the image in sequence, something like:
for (i = 0; i < img.rows; ++i) {
for (j = 0; j < img.cols; ++j) {
#pragma HLS PIPELINE II=1
auto pixel = img.read();
if (pixel != 0) {
// White pixel found: use i and j (the coordinates) or store them somewhere.
}
// Eventually write back the pixel into the image: img.write(pixel);
}
}
If the image is instead stored in a buffer like registers or BRAM, then the above loop over the rows and columns of the image can be parallelized. For instance:
const int kUnrollFactor = 4;
pixel_t img[H][W];
#pragma HLS ARRAY_PARTITION variable=img block factor=kUnrollFactor dim=2
for (i = 0; i < H; ++i) {
for (j = 0; j < W; ++j) {
#pragma HLS PIPELINE II=1
#pragma HLS UNROLL factor=kUnrollFactor
if (img[i][j] != 0) {
// White pixel found: use i and j (the coordinates) or store them somewhere.
}
}
}
As for eventually storing your result: since there can be at most W * H white pixels, you might need a buffer of W * H * log2(max(W, H)) bits.
Edit
Based on the updated question, the last part of the code might give some problems.
Since a definitions of AXI_STREAM and gray_IMAGE are not given, the data type of the stream (and in turn of the internal streams img_*) might not be comparable with 255 (the white pixel value).
Suppose the pixel is defined as a struct, then doing pixel == 255 would simply not compile. On the other end, if it is a "flatten" RGB array like ap_uint<24> (three 8bit pixels), comparing with 255 might be meaningless (you would instead need to compare it with 0xFFFFFF).
Otherwise, if the pixel type is integer or unsigned char, then comparing it with 255 or 0 would give no problems.

Related

Else statement executing even though the if statement is true

for school i am making an assignment, implementing astar search with the use of dictionaries. I have been trying a few things, but now i am stuck. in my first iteration the if statement if f_next < f: is true, so why does it not break out of the loop. It immediately goes to the else statement so my closed list contains both values from the if and else statement, how can i fix this. I have provided my code, some assignment information and the input below.
Given a grid-like graph, find the shortest path using A* between the two nodes with the maximum weight. Use the Euclidean as heuristic function, which is calculated between two points in a coordinate system (x1,y1) and (x2,y2) as follows:
d = p(x2 −x1)2 + (y2 −y1)2 (1) where, the nodes of the graph are represented as such points (see the input format below). You can assume that there exists a path between the two nodes with the maximum weight, and that all nodes have a unique weight.
Data format 1. The following is the input format expected by the algorithm for Task 1.
The program takes as input a list of nodes, represented as points in a coordinate system (e.g.,(x1,y1) and their weights separated by a ;.
In a new line the data-set of the graph edges are given following the pattern ”source node (xs,ys), end node (xe,ye), edge cost; ...”.
(x1), (y1), (weight1); ...(xn), (yn), (weightn);\n
(x1), (y1), (x2), (y2), (edgecost1); ...(xs), (ys), (xe), (ye), (edgecostm);\n
The expected output is the path from the start to the end node.
(xstart), (ystart)->(xi), (yi)...->(xend), (yend)\n
Input:
0, 0, 193; 0, 1, 146; 0, 2, 121; 0, 3, 174; 0, 4, 144; 1, 0, 191; 1, 1, 123; 1, 2, 151; 1, 3, 126; 1, 4, 163; 2, 0, 182; 2, 1, 107; 2, 2, 109; 2, 3, 125; 2, 4, 165; 3, 0, 169; 3, 1, 149; 3, 2, 180; 3, 3, 199; 3, 4, 199; 4, 0, 160; 4, 1, 148; 4, 2, 123; 4, 3, 197; 4, 4, 156
0, 0, 1, 0, 1; 0, 0, 0, 1, 1; 0, 1, 1, 1, 1; 0, 1, 0, 2, 1; 0, 2, 1, 2, 1; 0, 2, 0, 3, 1; 0, 3, 1, 3, 1; 0, 3, 0, 4, 1; 0, 4, 1, 4, 1; 1, 0, 2, 0, 1; 1, 0, 1, 1, 1; 1, 1, 2, 1, 1; 1, 1, 1, 2, 1; 1, 2, 2, 2, 1; 1, 2, 1, 3, 1; 1, 3, 2, 3, 1; 1, 3, 1, 4, 1; 1, 4, 2, 4, 1; 2, 0, 3, 0, 1; 2, 0, 2, 1, 1; 2, 1, 3, 1, 1; 2, 1, 2, 2, 1; 2, 2, 3, 2, 1; 2, 2, 2, 3, 1; 2, 3, 3, 3, 1; 2, 3, 2, 4, 1; 2, 4, 3, 4, 1; 3, 0, 4, 0, 1; 3, 0, 3, 1, 1; 3, 1, 4, 1, 1; 3, 1, 3, 2, 1; 3, 2, 4, 2, 1; 3, 2, 3, 3, 1; 3, 3, 4, 3, 1; 3, 3, 3, 4, 1; 3, 4, 4, 4, 1
I am trying to find a path between (0,0) and (3,4)
import collections
import math
import sys
class Graph:
"""Class to represent a Graph, as a list of weighted nodes and edges."""
def __init__(self):
"""Function to initialize a Graph object"""
self.node_g = {}
self.edge_g = collections.defaultdict(list)
pass
def add_node(self, node_id, weight):
"""Function to add a node to a Graph object."""
self.node_g[node_id] = weight
print(self.node_g)
pass
def add_edge(self, source_id, end_id, weight):
weightedge = (end_id, weight)
self.edge_g[source_id].append(weightedge)
pass
def __repr__(self):
return "nodes:% s edges:% s" % (self.node_g, self.edge_g)
def __str__(self):
return "From str method of graph: nodes are % s, " \
"edges are % s" % (self.node_g, self.edge_g)
def build_Graph(nodes, edges):
"""Function to build a grid-like Graph object from the input data.
Parameters
----------
nodes : list of nodes, each represented as coordinates, and node_weight.
For example: x1, y1, weight; x2, y2, weight; ...
edges : list of edges, each represented as source and end node coordintates, and edge_weight.
For example: x1, y1, x2, y2, weight; x3, y3, x4, y4, weight; ...
Return
----------
A Graph object.
"""
G = Graph()
for n in nodes:
aux = n.split(', ')
temp1 = int(aux[0])
temp2 = int(aux[1])
temp_node = (temp1, temp2)
G.add_node(temp_node, weight=int(aux[2]))
for e in edges:
aux = e.split(', ')
temp1 = int(aux[0])
temp2 = int(aux[1])
temp = (temp1, temp2)
auxn1 = int(aux[2])
auxn2 = int(aux[3])
auxn = (auxn1, auxn2)
G.add_edge(temp, auxn, weight=int(aux[4]))
return G
def print_output(nodes):
"""Function to print the shortest path between the two nodes with the highest weigths.
Parameters
----------
nodes : list of list of nodes (represented as: tuples of coordinates).
"""
# nodes = [x1, y1, x2, y2, x3, y3]
# Expected output: x1, y1->x2, y2->x3, y3
def astar_shortest_path(G, source_id, end_id, heuristic):
"""Function to return the shortest path between two nodes in a Graph"""
open_set = [source_id]
#print(open_set)
closed_set = []
g = 0
h = heuristic(source_id, end_id)
f = g + h
#print(G.edge_g[open_set[0]][0])
#print(G.edge_g[source_id])
#print(G.edge_g[end_id])
while len(open_set) > 0:
if source_id == end_id:
return closed_set
for index, item in enumerate(G.edge_g[open_set[0]]):
print(item)
var = item[0]
print(var)
if not index:
next = item[0]
g_next = item[1]
h_next = heuristic(item[0], end_id)
f_next = h_next + g_next
if f_next < f:
f += f_next
h += h_next
g += g_next
open_set.append(next)
print(open_set)
closed_set.append(open_set[0])
print(closed_set)
open_set.remove(open_set[0])
print(open_set)
else:
next_2 = item[0]
g_next_2 = item[1]
h_next_2 = heuristic(item[0], end_id)
f_next_2 = g_next_2 + h_next_2
if f_next_2 < f:
f += f_next_2
h += h_next_2
g += g_next_2
closed_set.append(open_set[0])
print(closed_set)
open_set.remove(open_set[0])
print(open_set)
open_set.append(next_2)
print(open_set)
#print(open_set)
def heuristic(a, b):
#print(a, b)
"""Function to compute the Euclidean distance between two nodes."""
dx = abs(b[0] - a[0]) ** 2
#print(dx)
dy = abs(b[1] - a[1]) ** 2
#print(dy)
return math.sqrt(dx + dy)
if __name__ == '__main__':
# Read the input
# The first line is made of a list of nodes, written as tuples of cartesian coordinates.
# For example: x1, y1, weight; x2, y2, weight; ...
# In the previous example, x1, y1, weight; is the first node
nodes = input().split('; ')
# The second line is made of edges, written as source and end node coordinates, and edge_weight.
# For example: x1, y1, x2, y2, weight; x3, y3, x4, y4, weight; ...
# In the previous example, x1, y1, x2, y2, weight; is the first edge
edges = input().split('; ')
# Build a grid graph from the input nodes and edges
G = build_Graph(nodes, edges)
print(G)
sort_edge = sorted(G.node_g, key=G.node_g.get)
max1 = sort_edge[-2]
#print(max1)
max2 = sort_edge[-1]
#print(max2)
# Find the two nodes with the highest weights in the graph
source_id = (0, 0) #max1
end_id = (3, 4) #max2
# Compute the path between the two nodes with the highest weight
# The source node is the one with the highest weigth
# You are free to customize the following function
s_path = astar_shortest_path(G, source_id, end_id, heuristic)
# Expected output format: list of lists of nodes (represented as: tuples of coordinates).
# For example: x1, y1->x2, y2->x3, y3
print_output(s_path)
#############

Pytorch, get the index of the first 0 in as mask?

I have a tensor that looks like: (1, 1, 1, 1, 1, 1, 1, 1, 0, 0).
I want to get the index where the first zero appears.
What would the be best way do this?
Not the best usage of argmin but it should work here I think:
>>> torch.tensor([1, 1, 1, 1, 1, 1, 1, 1, 0, 0]).argmin()
tensor(8)
try this:
your_target_value = 0
your_tensor = torch.tensor([1, 1, 1, 1, 1, 1, 1, 1, 0, 0])
(your_tensor == your_target_value).nonzero()[0] #first element
Output:
tensor([8])

Python: Converting Binary to Decimal

What I'm currently doing is a implementation of Genetic Algorithms. I have written my Crossover and mutation methods and now i'm currently writing my Fitness method.
I need to convert my list of 0s and 1s to decimal values for calculating distance.
My current output that I'm working with are a list of integer values of 1s and 0s. (Example below):
[[0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]]
<class 'list'>
I want to convert these numbers to their respected binary equivalent.
I have tried converting the list to groups of 4 and then calling a binaryToDecimal function to convert the bits to decimal values. However, Im getting an error 'TypeError: 'numpy.ndarray' object is not callable'.
I have summarized my code and this is what it looks like so far.
def converting_binary_to_decimal(L):
output = []
for l in L:
l = list(map(str, l))
sub_output = []
for j in range(0, len(l)-1, 4):
sub_output.append(int(''.join(l[j:j+4]), 2))
output.append(sub_output)
return output
def chunks(L, n):
for i in range(0, len(L), n):
yield L[i:i+n]
def fitness(child):
newList1=list(chunks(child[0], 4))
newList2=list(chunks(child[1], 4))
if __name__ == "__main__":
myFitness = fitness(afterMU)
A sample output of what i want is:
[[0, 13, 6, 8, 12, 8, 10, 9, 15], [0, 8, 7, 0, 4, 4, 1, 8, 15]]
Try this code.
def converting_binary_to_decimal(L):
output = []
for l in L:
l = list(map(str, l))
sub_output = []
for j in range(0, len(l)-1, 4):
sub_output.append(int(''.join(l[j:j+4]), 2))
output.append(sub_output)
return output
L = [[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1]]
converting_binary_to_decimal(L)
I think i figured it out.
x=[0, 1, 1, 0]
k = 4
n = len(x)//k
for i in range(n):
y = x[i*k:(i+1)*k]
y = [str(j) for j in y]
y = ''.join(y)
y = int(y,2)
print(y)
Thank you.

numpy packbits pack to uint16 array

I´ve got a 3D numpy bit array, I need to pack them along the third axis. So exactly what numpy.packbits does. But unfortunately it packs it only to uint8, but I need more data, is there a similar way to pack it to uint16 or uint32?
Depending on your machine's endianness it is either a matter of simple view casting or of byte swapping and then view casting:
>>> a = np.random.randint(0, 2, (4, 16))
>>> a
array([[1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1]])
>>> np.packbits(a.reshape(-1, 2, 8)[:, ::-1]).view(np.uint16)
array([53226, 23751, 25853, 64619], dtype=uint16)
# check:
>>> [bin(x + (1<<16))[-16:] for x in _]
['1100111111101010', '0101110011000111', '0110010011111101', '1111110001101011']
You may have to reshape in the end.

Conversion of numpy 2d array to ENVI binary file through gdal

I have SAR CEOS format files which consist of data file, leader file, null volume directory file and volume directory file.
I am reading the data file using gdal ReadAsArray and then I am doing operations on this 2d Array and now I want to save this 2d array as an ENVI binary file.
Kindly guide how to do this in Python 3.5.
Find help for Tutorial Website: https://pcjericks.github.io/py-gdalogr-cookbook/
Such as the example of
import gdal, ogr, os, osr
import numpy as np
def array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
cols = array.shape[1]
rows = array.shape[0]
originX = rasterOrigin[0]
originY = rasterOrigin[1]
driver = gdal.GetDriverByName('ENVI')
outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Byte)
outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
outband = outRaster.GetRasterBand(1)
outband.WriteArray(array)
outRasterSRS = osr.SpatialReference()
outRasterSRS.ImportFromEPSG(4326)
outRaster.SetProjection(outRasterSRS.ExportToWkt())
outband.FlushCache()
def main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
reversed_arr = array[::-1] # reverse array so the tif looks like the array
array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,reversed_arr) # convert array to raster
if __name__ == "__main__":
rasterOrigin = (-123.25745,45.43013)
pixelWidth = 10
pixelHeight = 10
newRasterfn = 'test.tif'
array = np.array([[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array)

Resources