SceneKit custom geometry .. SCNGeometrySource with 16-bit integers - scenekit

Using SceneKit to build some large custom geometries, in order to keep array sizes as small as possible, I fed SCNGeometrySource with vectors with (x,y,z) as short (Int16) integers, as follows:
let vertexSource = SCNGeometrySource(data: dataContent!,
semantic: SCNGeometrySourceSemanticVertex, vectorCount: 4960,
floatComponents: false, componentsPerVector: 3, bytesPerComponent: 2,
dataOffset: 0, dataStride: 6)
.. however, this data was not acceptable, generating the error:
SceneKit: error, C3DMeshSourceGetValueAtIndexAsVector3 - Type not supported
Question: What forms of vector components does SceneKit support?
After writing this question I'm going to try trial & error to see what happens with triples and quads of Float32, Int32, etc. I know Float64 does work but I don't need better than ±2^15 precision, so why waste memory? Perhaps someone can provide a definitive answer .. Apple's documentation appears to not do so.

Related

HALCON - How to read low resolution ECC200 datacode in halcon?

I have the need to read this low quality ECC code using halcon 20.
I have tried all possible parameters but cannot find any combination that is able to read this code.
What seems strange to me is that if I have a look at the example codes, there are images that are even worse than this and those are read without problems.
here is my current code that is NOT able to read this:
create_data_code_2d_model ('Data Matrix ECC 200', ['default_parameters','small_modules_robustness','module_size_min'], ['maximum_recognition','high','1'], DataCodeHandleMaximum)
set_data_code_2d_param (DataCodeHandleMaximum,['symbol_cols','symbol_rows','slant_max','timeout'],[26,12,0.52,10000])
find_data_code_2d (ImageReduced, SymbolXLDs, DataCodeHandleMaximum, ['stop_after_result_num'], [200], ResultHandles, DecodedDataStrings)
any help appreciated
Image seems to be a bit out of focus, so it needs a bit of sharpening filter:
create_data_code_2d_model ('Data Matrix ECC 200', 'default_parameters', 'maximum_recognition', DataCodeHandle)
emphasize (Image, ImageEmphasize, 7, 7, 1)
find_data_code_2d (ImageEmphasize, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)

Scalar multiplication of tensors

In TensorFlow Core for Python there is an operation called tf.math.scalar_mul.
I would like to scale tensors in TensorFlow.js. By trying for instance a * 0.1 I get an error message (at least from Typescript):The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2362).
Is scaling tensors applicable without making them arrays, scale elementwise then transform back to tensors?
Though, tf.scalar can be used, one can also use direclty tensor.mul(number) like the following
tf.tensor([1, 2, 3, 4]).mul(5).print(); // [5, 10, 15, 20]
I found the answer in the API documentation. For multiplying a tensor a with 5, just a.mul(tf.scalar(5)).

How do I implement a controlled Rx in Cirq/Tensorflow Quantum?

I am trying to implement a controlled rotation gate in Cirq/Tensorflow Quantum.
The readthedocs.io at https://cirq.readthedocs.io/en/stable/gates.html states:
"Gates can be converted to a controlled version by using Gate.controlled(). In general, this returns an instance of a ControlledGate. However, for certain special cases where the controlled version of the gate is also a known gate, this returns the instance of that gate. For instance, cirq.X.controlled() returns a cirq.CNOT gate. Operations have similar functionality Operation.controlled_by(), such as cirq.X(q0).controlled_by(q1)."
I have implemented
cirq.rx(theta_0).on(q[0]).controlled_by(q[3])
I get the following error:
~/.local/lib/python3.6/site-packages/cirq/google/serializable_gate_set.py in
serialize_op(self, op, msg, arg_function_language)
193 return proto_msg
194 raise ValueError('Cannot serialize op {!r} of type {}'.format(
--> 195 gate_op, gate_type))
196
197 def deserialize_dict(self,
ValueError: Cannot serialize op cirq.ControlledOperation(controls=(cirq.GridQubit(0, 3),), sub_operation=cirq.rx(sympy.Symbol('theta_0')).on(cirq.GridQubit(0, 0)), control_values=((1,),)) of type <class 'cirq.ops.controlled_gate.ControlledGate'>
I have the qubits and symbols initialized as:
q = cirq.GridQubit.rect(1, 4)
symbol_names = x_0, x_1, x_2, x_3, theta_0, theta_1, z_2, z_3
I do re-use the circuits with various circuits.
My question: How do I properly implement a controlled Rx in Cirq/Tensorflow Quantum?
P.S. I can't find a tag for Google Cirq
Follow up:
How does this generalize to the similar situations of Controlled Ry and controlled Rz?
For Rz I found a gate decomposition at https://threeplusone.com/pubs/on_gates.pdf, involving H.on(q1), CNOT(q0, q1), H.on(q2), but this is not yet an CRz with an arbitrary angle. Would I introduce the angle before the H?
For the Ry, I did not find a decomposition yet, neither the CRy.
What you have is a completely correct implementation of a controlled X rotation in Cirq. It can be used in simulation and other things like cirq.unitary without any issues.
TFQ only supports a subset of gates in Cirq. For example a cirq.ControlledGate can have an arbitrary number of control qubits, which in some cases can make it harder to decompose down to primitive gates that are compatible with NiSQ hardware platforms (This is why cirq.decompose doesn't do anything to ControlledOperations). TFQ only supports these primitive style gates , for a full list of the supported gates, you can do:
tfq.util.get_supported_gates().keys()
In your case it is possible to come up with a simpler implementation of this gate. First we can note that cirq.rx(some angle) is equal to cirq.X**(some angle / pi) offset by a global phase:
>>> a = cirq.rx(0.3)
>>> b = cirq.X**(0.3 / np.pi)
>>> cirq.equal_up_to_global_phase(cirq.unitary(a), cirq.unitary(b))
True
Lets move to using X now. Then the operation we are after is:
>>> qs = cirq.GridQubit.rect(1,2)
>>> a = (cirq.X**0.3)(qs[0]).controlled_by(qs[1])
>>> b = cirq.CNOT(qs[0], qs[1]) ** 0.3
>>> cirq.equal_up_to_global_phase(cirq.unitary(a), cirq.unitary(b))
True
Since cirq.CNOT is in the TFQ supported gates it should be serializable without any issues. If you want to make a symbolized version of the gate you can just replace the 0.3 with a sympy.Symbol.
Answer to follow up: If you want to do a CRz you can do the same thing you did above, swapping out the CNOT gate for the CZ gate. For CRy it's not as easy. For that I would recommend doing some combination of: cirq.Y(0) and cirq.YY(0, 1).
Edit: tfq-nightly builds and likely releases after 0.4.0 now include support for arbitrary controlled gates. So on these versions of tfq you could also do things like cirq.Y(...).controlled_by(...) to achieve the desired result now too.

Function imwrite on imageio (Python) seems to be rescaling image data

The function imwrite() on imageio (Python) seems to be rescaling image data prior to saving. My image data has values in the range [30, 255] but when I save it, it stretches the data so the final image spreads from [0, 255], hence creating "holes" in the histogram so as increasing overall contrast.
Is there any parameter to fix this and make imwrite() not to modify the data?
Thanks
So far I am setting a pixel to 0 to prevent this from happening:
prediction[0, 0, 0] = 0
(prediction is a [1024, 768, 3] array containing a colour photograph)
imageio.imwrite('prediction.png', prediction)
Fixed! I was using uint32 values instead of uint8, then imwrite() seems to perform some scaling corrections because it expects uint8 type. The problem is solved using:
prediction = np.round(prediction*255).astype('uint8')
Instead of converting to 32-bit integer, which I did at the beginning:
prediction = np.round(prediction*255).astype(int)

CNN with RGB input and BW binary output

I am a beginner to deep learning and I am working with Keras built on top of Tensorflow. I am trying to using RGB images (540 x 360) resolution to predict bounding boxes.
My labels are binary (black/white) 2 dimensional np array of dimensions (540, 360) where all pixels are 0 except for the box edges which are a 1.
Like this:
[[0 0 0 0 0 0 ... 0]
[0 1 1 1 1 0 ... 0]
[0 1 0 0 1 0 ... 0]
[0 1 0 0 1 0 ... 0]
[0 1 1 1 1 0 ... 0]
[0 0 0 0 0 0 ... 0]]
There can be more than one bounding box in every picture. A typical image could look like this:
So, my input has the dimension (None, 540, 360, 3), output has dimensions (None, 540, 360) but if I add an internal array I can change the shape to (None, 540, 360, 1)
How would I define a CNN model such that my model could fit this criteria? How can I design a CNN with these inputs and outputs?
You have do differentiate between object detection and object segmentation. While both can be used for similar problems, the underlying CNN architectures look very different.
Object detection models use a CNN classification/regression architecure, where the output refers to the coordinates of the bounding boxes. It's common practice to use 4 values belonging to vertical center, horizontal center, width and height of each bounding box. Search for Faster R-CNN, SSD or YOLO to find popular object detection models for keras. In your case you would need to define a function that converts the current labels to the 4 coordinates I mentioned.
Object segmentation models commonly use an architecture referred to as encoder-decoder networks, where the original image is scaled down and compressed on the first half and then brought back to it's original resolution to predict a full image. Search for SegNet, U-Net or Tiramisu to find popular object segmentation models for keras. My own implementation of U-Net can be found here. In your case you would need to define a custom function, that fills all the 0s inside your bounding boxes with 1s. Understand that this solution will not predict bounding boxes as such, but segmentation maps showing regions of interest.
What is right for you, depends on what precisely you want to achieve. For getting actual bounding boxes you want to perform an object detection. However, if you're interested in highlighting regions of interest that go beyond rectangle windows a segmentation may be a better fit. In theory, you can use your rectangle labels for a segmentation, where the network will learn to create better masks than the inaccurate segmentation of the ground truth, provided you have enough data.
This is a simple example of how to write intermediate layers to achieve the output. You can use this as a starter code.
def model_360x540(input_shape=(360, 540, 3),num_classes=1):
inputs = Input(shape=input_shape)
# 360x540x3
downblock0 = Conv2D(32, (3, 3), padding='same')(inputs)
# 360x540x32
downblock0 = BatchNormalization()(block0)
downblock0 = Activation('relu')(block0)
downblock0_pool = MaxPooling2D((2, 2), strides=(2, 2))(block0)
# 180x270x32
centerblock0 = Conv2D(1024, (3, 3), padding='same')(downblock0_pool)
#180x270x1024
centerblock0 = BatchNormalization()(center)
centerblock0 = Activation('relu')(center)
upblock0 = UpSampling2D((2, 2))(centerblock0)
# 180x270x32
upblock0 = concatenate([downblock0 , upblock0], axis=3)
upblock0 = Activation('relu')(upblock0)
upblock0 = Conv2D(32, (3, 3), padding='same')(upblock0)
# 360x540x32
upblock0 = BatchNormalization()(upblock0)
upblock0 = Activation('relu')(upblock0)
classify = Conv2D(num_classes, (1, 1), activation='sigmoid')(upblock0)
#360x540x1
model = Model(inputs=inputs, outputs=classify)
model.compile(optimizer=RMSprop(lr=0.001), loss=bce_dice_loss, metrics=[dice_coeff])
return model
The downblock represents the block of layers which perform downsampling(MaxPooling2D).
The centerblock has no sampling layer.
The upblock represents the block of layers which perform up sampling(UpSampling2D).
So here you can see how (360,540,3) is being transformed to (360,540,1)
Basically, you can add such blocks of layers to create your model.
Also check out Holistically-Nested Edge Detection which will help you better with the edge detection task.
Hope this helps!
I have not worked with keras but I will provide a solution approach in more generalized way which can be used on any framework.
Here is full procedure.
Data preparation: I know your labels are edges of boxes which will also work but i will recommend that instead of edges you prepare dataset marking complete box like given in sample (I have marked for two boxes). Now your dataset have three classes (Box,Edges of box and background). Create two lists, Image and label.
Get a pre-trained model (RESNET-51 recommended) solver and train prototxt from here, Remove fc1000 layer and add de-convolution/up-sampling layers to match your input size. use paddding in first layer to make it square and crop in deconvolution layer to match input output dimensions.
Transfer weights from previously trained network (Original) and train your network.
Test your dataset and create bounding boxes using detected blobs.

Resources