difference between CV_32FC3 and CV_64FC3 in OpenCV? - debugging

I was testing around with OpenCV matrices and the display function and had this bug. It took me more than half a day to reveal it:
I originally tried to display OpenCV matrices regardless of the type of matric e.g. CvMat or Mat, ...
with a display method recommended by Mr vasile from another post of mine Multi channel Mat display function
The display method simply fetches all data of the matrix to cout stream
this is my program:
// First: CV_32FC3 works OK
float objpts[12] = {0, 105, 105, 0, 0, 0, 105, 105, 0, 0, 0, 0};
CvMat objptsmat = cvMat( 1, 4, CV_32FC3, objpts);
CvMat* objectPoints = &objptsmat;
CvMatShow(objectPoints);
getchar();
output:
// Second: CV_64FC3 crashes
float objpts[12] = {0, 105, 105, 0, 0, 0, 105, 105, 0, 0, 0, 0};
CvMat objptsmat = cvMat( 1, 4, CV_64FC3, objpts);
CvMat* objectPoints = &objptsmat;
CvMatShow(objectPoints);
getchar();
output:
they should be both the same. Right??!!

In the second example, you should have the array declared as
double objpts[12] = {0, 105, 105, 0, 0, 0, 105, 105, 0, 0, 0, 0};
You can read CV_xxtCn as
xx: number of bits
t: type (F = floating point type, S = signed integer, U = unsigned integer)
n: number of channels

Related

How can I create a random array between a range of two other arrays?

I need to generate an array of random 20 bytes between a given range of arrays. Since arrays are comparable in Rust, this works:
let low = [0u8; 20];
let high = [2u8; 20];
assert_eq!(true, low < high);
assert_eq!(false, low > high);
assert_eq!(true, low == [0u8; 20]);
For these bounds:
let low: [u8; 20] = [98, 0, 1, 0, 2, 6, 99, 3, 0, 5, 23, 3, 5, 6, 11, 8, 0, 2, 0, 17];
let high: [u8; 20] = [99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
These would be a valid result:
[98, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
These are not:
[98, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
I want to do something like:
use rand::prelude::*;
fn main() {
let low = [0u8; 20];
let high = [2u8; 20];
let value = rand::thread_rng().gen_range(low, high);
println!("{:?}", value);
}
but I get following error:
error[E0277]: the trait bound `[u8; 20]: rand::distributions::uniform::SampleUniform` is not satisfied
--> src\main.rs:6:36
|
6 | let value = rand::thread_rng().gen_range(low, high);
| ^^^^^^^^^ the trait `rand::distributions::uniform::SampleUniform` is not implemented for `[u8; 20]`
I tried implementing SampleUniform and UniformSampler without much success. Is there a simple way to implement this?
If you want to treat the byte arrays as big integers, use the
num-bigint crate with the rand feature enabled:
use bigint::{ToBigInt, RandBigInt};
let low = -10000.to_bigint().unwrap();
let high = 10000.to_bigint().unwrap();
let b = rng.gen_bigint_range(&low, &high);
You could also use unsigned integers instead of signed. There are methods to convert to and from big endian byte arrays:
from_bytes_be
to_bytes_be
See also:
How do I generate a random num::BigUint?

Low cost Image to NSData conversion for feeding SCNTechnique's sampler2D inputs

Sometimes the only way to pass precious data from CPU to GPU is by hiding it in textures.
I tried to trick SCNTechnique and simply pass [NSData dataWithBytes:length:] or a CGDataProviderRef containing my neatly prepared raw pixel data bytes, but SceneKit is smart enough to detect my sinister attempts.
But I did not give up, and found a loophole:
[_sceneView.technique setValue: UIImagePNGRepresentation(encodeInSinglePixelUIImage(pos.x, pos.y)) forKey:#"blob_pos_"];
Encoding and decoding single pixel PNGs at 60fps on a mobile device is something you can afford, on an iPhone X it just costs 2ms and keeps your palm a little bit warmer.
However I do not need any heat-generating features till november, so I was wondering if there's a cool alternative to this method.
The most efficient way I found is constructing floating point RGB TIFFs.
It's still not super fast, consuming 0.7ms on the iPhone X, but a lot faster than the PNG method.
Having a float texture also have the benefits of direct float transfer, that is, no encoding to multiple uint8 RGBA values on the CPU and reconstructing floats on the GPU.
Here's how:
NSData * tiffencode(float x, float y)
{
const uint8_t tags = 9;
const uint8_t headerlen = 8+2+tags*12+4;
const uint8_t width = 1;
const uint8_t height = 1;
const uint8_t datalen = width*height*3*4;
static uint8_t tiff[headerlen+datalen] = {
'I', 'I', 0x2a, 0, //little endian/'I'ntel
8, 0, 0, 0, //index of metadata
tags, 0,
0x00, 1, 4, 0, 1, 0, 0, 0, width, 0, 0, 0, //width
0x01, 1, 4, 0, 1, 0, 0, 0, height, 0, 0, 0, //height
0x02, 1, 3, 0, 1, 0, 0, 0, 32, 0, 0, 0, //bits per sample(s)
0x06, 1, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, //photometric interpretation: RGB
0x11, 1, 4, 0, 1, 0, 0, 0, headerlen, 0, 0, 0,//strip offset
0x15, 1, 3, 0, 1, 0, 0, 0, 3, 0, 0, 0, //samples per pixel: 3
0x16, 1, 4, 0, 1, 0, 0, 0, height, 0, 0, 0, //rows per strip: height
0x17, 1, 4, 0, 1, 0, 0, 0, datalen, 0, 0, 0, //strip byte length
0x53, 1, 3, 0, 1, 0, 0, 0, 3, 0, 0, 0, //sampleformat: float
0, 0, 0, 0, //end of metadata
//RGBRGB.. pixeldata here
};
float *rawData = tiff+headerlen;
rawData[0] = x;
rawData[1] = y;
NSData *data = [NSData dataWithBytes:&tiff length:sizeof(tiff)];
return data;
}
Useful TIFF links I used:
http://www.fileformat.info/format/tiff/corion.htm
http://paulbourke.net/dataformats/tiff/
https://www.fileformat.info/format/tiff/egff.htm
https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html

Dual pivot quick sort algorithm

I was analyzing the code for Arrays.sort() method in java . My question is for what values of integer array a[] will this code return true ?
if (less < e1 && e5 < great)
After Sorting left and right parts recursively, excluding known pivots for what value of array a[] will the center part become too large (comprises > 4/7 of the array) ?
Given QUICKSORT_THRESHOLD = 286 .
Array size cannot be more than 286
Any example of int array please .
It happens when all candidates for pivots are close to either the maximum or the minimum value of the array.
java.util.DualPivotQuicksort#sort() chooses the pivots from 5 positions in the array:
int seventh = (length >> 3) + (length >> 6) + 1;
int e3 = (left + right) >>> 1; // The midpoint
int e2 = e3 - seventh;
int e1 = e2 - seventh;
int e4 = e3 + seventh;
int e5 = e4 + seventh;
So, in order to construct an array that satisfies the condition, we need to fill those 5 positions with extreme values. For example:
int[] x = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, /* e1 = 10 */
0, 0, 0, 0, 0, 0, -1, /* e2 = 17 */
0, 0, 0, 0, 0, 0, 0, /* e3 = 24 */
0, 0, 0, 0, 0, 0, 1, /* e4 = 31 */
0, 0, 0, 0, 0, 0, 2, /* e5 = 38 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
Arrays.sort(x);
And a non-trivial case where the method changes the boundaries of the central part before sorting it:
int[] x = {
70, 66, 11, 24, 10, 28, 58, 13, 19, 90, 15,
79, 16, 69, 39, 14, 10, 16,
40, 59, 47, 77, 90, 50, 50,
50, 16, 76, 86, 70, 33, 90,
24, 35, 73, 93, 87, 19, 91,
73, 87, 22, 15, 24, 92, 34, 35, 98, 11, 40
};

Why can't I do an equality test of a synth parameter?

I'm mystified. In this code:
SynthDef(\acid,
{
|out, gate = 1, freq, myParam, amp, cutoff, resonance, filtEnvAmt|
var env, audio, filtEnv;
if (myParam == \something, { freq = 200; });
env = Linen.kr(gate, 0, 1, 0, doneAction: 2);
audio = LFSaw.ar(freq, mul: amp);
filtEnv = Line.kr(midicps(cutoff + filtEnvAmt), midicps(cutoff), 0.2);
audio = RLPFD.ar(audio, ffreq: filtEnv + MouseX.kr(0, 5000), res: MouseY.kr(0, 1), dist: 0);
Out.ar(out, audio * env);
}
).add;
b = Pbind(*[
out: 0,
instrument: \acid,
stepsPerOctave: 19,
scale: [0, 3, 5, 8, 11, 14, 17],
octave: 3,
degree: Pseq([0, \, 3, 3, 4, 4, 9, 4, 4]),
myParam: \something,
//prevFreq: Pseq([0, 0, 0, 0, 9, 0, 0, 0, 0]),
dur: Pseq([0.4, 0.4, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1]),
cutoff: Pseq([60, \, 50, 60, 80, 60, 90, 80, 50]),
filtEnvAmt: Pseq([20, \, 20, 20, 20, 20, -10, 20, 20]),
resonance: Pseq([0.5, \, 0.5, 0.5, 0.5, 0.5, 0.3, 0.5, 0.5])
]);
b.play;
..the equality test myParam == \something never returns true, despite the fact that the Pbind is clearly sending \something each time. No other value will work either: 0, nil etc.
The equality tests myParam == myParam and \something == \something do work however, so in these cases I get a monotone melody.
I can only guess that a Pbind sends each value in some kind of wrapper, but I've no idea how to then check them from inside the synth. Can anyone help?
First: you can't send symbols to a synth control. You can only send numbers.
Second: your example doesn't say what freq should be if the test is false. In fact, you should write it in more of a dataflow style such as:
freq = if(testcondition, 200, 300);
That's the kind of thing that will work in a synthdef.
Third is a slightly frustrating thing in sc language, which is that the == message is always evaluated at synthdef compile time - the equality is checked once, and then never again. In order to have "live" equality checking, you can use this slightly clunky expression:
BinaryOpUGen("==", thinga, thingb)
So in summary you might write
freq = if(BinaryOpUGen("==", myParam, 1), 200, 300);

How to initialize __m128i array statically in gcc?

I am porting some SSE optimization code from Windows to Linux. And I found that the following code, which works well in MSVC, won't work in GCC.
The code is to initialize an array of __m128i. Each __mi28i contains 16 int8_t. It does compile with gcc but the result is not as expected.
Actually, as gcc defines __m128i as long long int, the code will initialize an array like:
long long int coeffs_ssse3[4] = {64, 83, 64, 36}.
I googled and was told that "The only portable way to initialize a vector is to use _mm_set_XXX intrinsics." However, I want to know is there any other way to initialize the __m128i array? Better statically, and don't need to modify the following code much (since I have tons of code in the following format). Any suggestion is appreciated.
static const __m128i coeffs_ssse3[4] =
{
{ 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0},
{ 83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1},
{ 64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0},
{ 36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, 83, 0,-36,-1}
};
It seems that gcc doesn't treat the __m128* types as being candidates for aggregate initialization. Since they aren't standard types, this behavior will vary from compiler to compiler. One approach would be to declare the array as an aligned array of 8-bit integers, then just cast a pointer to it:
static const int8_t coeffs[64] __attribute__((aligned(16))) =
{
64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0,
83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1,
64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0,
36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, 83, 0,-36,-1
};
static const __m128i *coeffs_ssse3 = (__m128i *) coeffs;
However, I don't think this syntax (__attribute__((aligned(x)))) is supported by Visual Studio, so you would need some #ifdef trickery in there to use the right directives to achieve the alignment that you want on all of your target platforms.

Resources