Why is this set of F rotating in this locus - webgl

In this code , I am not able to understand why the rotation is not in circular locus. This may be basic logic behind this but i can't understand why this so random locus.
I am rotating camera in orbital motion but it is not following it.
In my knowledge, i created a orbital motion camera and inverse of that is view matrix. So, view matrix will transform the world space for this result.Is there any fault in my thinking process ?
"use strict";
const vertexShader = `#version 300 es
in vec4 a_position;
in vec4 a_color;
out vec4 v_color;
uniform mat4 u_matrix;
void main(){
gl_Position = u_matrix*a_position;
v_color = a_color;
}
`;
const fragShader = `#version 300 es
precision highp float;
in vec4 v_color;
out vec4 frag_color;
void main(){
frag_color = v_color;
}
`;
var cameraAngleDegree = 0;
var cameraAngle = 0;
const radius = 100;
var increment = 1;
var numFs = 5;
function main() {
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl2");
if (!gl) {
return;
}
requestAnimationFrame(function() {
init(gl);
});
}
function init(gl) {
const program = webglUtils.createProgramFromSources(gl, [vertexShader, fragShader]);
const apositionLoc = gl.getAttribLocation(program, 'a_position');
const acolorLoc = gl.getAttribLocation(program, 'a_color');
const umatrixLoc = gl.getUniformLocation(program, 'u_matrix');
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
let positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setGeometry(gl);
gl.enableVertexAttribArray(apositionLoc);
let size = 3;
let type = gl.FLOAT;
let normalize = false;
let stride = 0;
let offset = 0;
gl.vertexAttribPointer(apositionLoc, size, type, normalize, stride, offset);
let colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
setColor(gl);
gl.enableVertexAttribArray(acolorLoc);
size = 3;
type = gl.UNSIGNED_BYTE;
normalize = true;
stride = 0;
offset = 0;
gl.vertexAttribPointer(acolorLoc, size, type, normalize, stride, offset);
let fov = degreeToRadian(60);
cameraAngle = degreeToRadian(cameraAngleDegree);
function degreeToRadian(deg) {
return deg * Math.PI / 180;
}
function radToDegree(rad) {
return rad * (180) / Math.PI;
}
drawScene();
// webglLessonsUI.setupSlider("#cameraAngle", { value: radToDegree(cameraAngle), slide: updateCameraAngle, min: -360, max: 360 });
// function updateCameraAngle(event, ui) {
// cameraAngle = degreeToRadian(ui.value);
// drawScene();
// }
function drawScene() {
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);
gl.useProgram(program);
let aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
let projection = m4.perspective(fov, aspect, 1, 1000);
const fPosition = [radius, 0, 0];
cameraAngleDegree += increment;
cameraAngle =degreeToRadian(cameraAngleDegree);
let camera = m4.yRotation(cameraAngle);
camera = m4.translate(camera, 0, 100, 300);
let cameraPosition = [camera[12], camera[13], camera[14]];
// let up = [0, 1, 0];
// camera = m4.lookAt(cameraPosition, fPosition, up);
let viewMatrix = m4.inverse(camera);
let viewProjection = m4.multiply(projection, viewMatrix);
for (var ii = 0; ii < numFs; ++ii) {
var angle = ii * Math.PI * 2 / numFs;
var x = Math.cos(angle) * radius;
var z = Math.sin(angle) * radius;
var matrix = m4.translate(viewProjection, x, 0, z);
// Set the matrix.
gl.uniformMatrix4fv(umatrixLoc, false, matrix);
// Draw the geometry.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 16 * 6;
gl.drawArrays(primitiveType, offset, count);
}
// gl.uniformMatrix4fv(umatrixLoc, false, viewProjection);
// var primitives = gl.TRIANGLES;
// var count = 16 * 6;
// var offset = 0;
// gl.drawArrays(primitives, offset, count);
// }
requestAnimationFrame(function() {
init(gl)
});
}
}
function setGeometry(gl) {
let positions = new Float32Array([
0, 0, 0,
0, 150, 0,
30, 0, 0,
0, 150, 0,
30, 150, 0,
30, 0, 0,
// top rung front
30, 0, 0,
30, 30, 0,
100, 0, 0,
30, 30, 0,
100, 30, 0,
100, 0, 0,
// middle rung front
30, 60, 0,
30, 90, 0,
67, 60, 0,
30, 90, 0,
67, 90, 0,
67, 60, 0,
// left column back
0, 0, 30,
30, 0, 30,
0, 150, 30,
0, 150, 30,
30, 0, 30,
30, 150, 30,
// top rung back
30, 0, 30,
100, 0, 30,
30, 30, 30,
30, 30, 30,
100, 0, 30,
100, 30, 30,
// middle rung back
30, 60, 30,
67, 60, 30,
30, 90, 30,
30, 90, 30,
67, 60, 30,
67, 90, 30,
// top
0, 0, 0,
100, 0, 0,
100, 0, 30,
0, 0, 0,
100, 0, 30,
0, 0, 30,
// top rung right
100, 0, 0,
100, 30, 0,
100, 30, 30,
100, 0, 0,
100, 30, 30,
100, 0, 30,
// under top rung
30, 30, 0,
30, 30, 30,
100, 30, 30,
30, 30, 0,
100, 30, 30,
100, 30, 0,
// between top rung and middle
30, 30, 0,
30, 60, 30,
30, 30, 30,
30, 30, 0,
30, 60, 0,
30, 60, 30,
// top of middle rung
30, 60, 0,
67, 60, 30,
30, 60, 30,
30, 60, 0,
67, 60, 0,
67, 60, 30,
// right of middle rung
67, 60, 0,
67, 90, 30,
67, 60, 30,
67, 60, 0,
67, 90, 0,
67, 90, 30,
// bottom of middle rung.
30, 90, 0,
30, 90, 30,
67, 90, 30,
30, 90, 0,
67, 90, 30,
67, 90, 0,
// right of bottom
30, 90, 0,
30, 150, 30,
30, 90, 30,
30, 90, 0,
30, 150, 0,
30, 150, 30,
// bottom
0, 150, 0,
0, 150, 30,
30, 150, 30,
0, 150, 0,
30, 150, 30,
30, 150, 0,
// left side
0, 0, 0,
0, 0, 30,
0, 150, 30,
0, 0, 0,
0, 150, 30,
0, 150, 0,
]);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)
}
function setColor(gl) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Uint8Array([
// left column front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// top rung front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// middle rung front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// left column back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// top rung back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// middle rung back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// top
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
// top rung right
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
// under top rung
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
// between top rung and middle
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
// top of middle rung
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
// right of middle rung
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
// bottom of middle rung.
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
// right of bottom
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
// bottom
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
// left side
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
]),
gl.STATIC_DRAW);
}
main();
<!DOCTYPE html>
<html>
<head>
<title>Traingle Webgl 2</title>
<style type="text/css">
#import url("https://webglfundamentals.org/webgl/resources/webgl-tutorials.css");
body {
margin: 0;
}
button {
position: absolute;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="uiContainer">
<div id="ui">
<div id="cameraAngle"></div>
</div>
</div>
<!--
for most samples webgl-utils only provides shader compiling/linking and
canvas resizing because why clutter the examples with code that's the same in every sample.
See https://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html
and https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
for webgl-utils, m3, m4, and webgl-lessons-ui.
-->
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-ui.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<script src="https://greggman.github.io/webgl-helpers/webgl-gl-error-check.js"></script>
<script type="text/javascript" src="js/lookat.js"></script>
<!-- <script type="text/javascript" src="js/camera.js"></script> -->
</body>
</html>

If I understand your question, the problem you see is it looks like the camera is getting closer to and further from the Fs
The issue is the vertex data for the Fs are built so the top left front corner is at 0,0,0, from that they go +X 100 units (so 100 units wide), +Y 150 units (so 100 units tall), and +Z 30 units so 30 units deep
So then, when you draw them around a 100 unit circle their origin is the part you are positioning and you get this
The image is top down so the Fs are just a rectangle. The green circle is the local origin of each F, its local 0,0,0. The other vertices of the F are relative to that local origin so they are closer to the outer circle (the orbit of the camera) on one side and further on the other
You can fix it by moving the Fs -50 in X and -15 in Z. In other words
var angle = ii * Math.PI * 2 / numFs;
var x = Math.cos(angle) * radius - 50;
var z = Math.sin(angle) * radius - 15;
Which gives you this situation
The local origin of each F is no longer on the circle.
You could also fix it by centering the F vertex data, go through all the vertices and subtract 50 from X and 15 from Z. That would give you this situation
Now the origin of each F is centered and it's local origin is on the circle.
Yet another way to fix it would be to compute the extents of the group of Fs, compute the center of the extents, move the center of the camera orbit there which would be this situation

Related

Understanding spacer/z3 unsat proof

We use spacer as a backend CHC solver and want to get proof when the result is unsat.
I think that the proof is sufficient to construct a counterexample(a graph reachable to a bad state) but spacer's output is difficult to understand for me. There are some unfamiliar words like asserted or hyper-res.
I couldn't find any document to understand that output. If there is any, please tell me.
I'm really happy if I can construct a counterexample similar to Eldarica's one[0].
For example,
0: FALSE -> 1
1: main_h_30(0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 1) -> 2
2: main_h_28(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 3
3: main_h_24(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 4
4: main_h_22(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 5
5: main_h_21(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 6
6: main_h_18(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1) -> 7
7: main_h_16(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1) -> 8
8: main_h_13(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1) -> 9
9: main_h_11(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1) -> 10
10: main_h_9(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1) -> 11
11: main_h_8(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1) -> 12
12: main_h_7(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 13
13: main_h_6(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 14
14: main_h_5(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 15
15: main_h_4(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 16
16: main_h_3(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 17
17: main_h_2(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) -> 18
18: main_h_1(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)
[0] http://logicrunch.it.uu.se:4096/~wv/eldarica/?ex=Prolog%2Flistcounter.unsat

OpenCV, how can we normalize a Mat min to max and max to min?

I want to normalize a Mat to the min value goes to 255 and max goes to 0 (normalize the Mat between 0~255).
For example, if we have an array like [0.02, 0.002, 0.0002] after normalization I want to get a result like this: [3, 26, 255], but now when I am using NORM_MINMAX I got [255, 26, 3].
But I did not find any function to do the inverted operation of the NORM_MINMAX.
Code used:
cv::Mat mat(10, 10, CV_64F);
mat.setTo(0);
mat.row(0) = 0.02;
mat.row(1) = 0.002;
mat.row(2) = 0.0002;
cv::normalize(mat, mat, 255, 0, cv::NORM_MINMAX);
mat.convertTo(mat, CV_8UC1);
std::cout << mat << std::endl;
Result is:
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
26, 26, 26, 26, 26, 26, 26, 26, 26, 26;
3, 3, 3, 3, 3, 3, 3, 3, 3, 3;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But I want the inverse of the above result.
Update: When I subtract 255 from the mat like:
cv::subtract(255, mat, mat, mat); // the last mat acts as mask
std::cout << mat << std::endl;
Result is:
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
229, 229, 229, 229, 229, 229, 229, 229, 229, 229;
252, 252, 252, 252, 252, 252, 252, 252, 252, 252;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
I finally found the way how to calculate, below are the steps:
By using inverse proportions formula, we can easily calculate the inverse of the NORM_MINMAX
x = a*b/c
Where the a= min value of the mat element, b=255 (max value), and c= the element which we want to calculate it.
cv::Mat mat(10, 10, CV_64F);
mat.setTo(0);
mat.row(0) = 0.02;
mat.row(1) = 0.002;
mat.row(2) = 0.0002;
std::cout << mat<< std::endl;
// craete a mask
cv::Mat mask(mat.size(), CV_8U);
mask.setTo(0);
mask.row(0) = 255;
mask.row(1) = 255;
mask.row(2) = 255;
// find the min value
double min;
cv::minMaxLoc(mat, &min, nullptr, nullptr, nullptr, mask);
std::cout << "min=" << min << std::endl;
// unfortunately opencv divide operation does not support mask, so we need some extra steps to perform.
cv::Mat result, maskNeg;
cv::divide(min*255, mat, result); // this is the magic line
cv::bitwise_not(mask, maskNeg);
mat.copyTo(result, maskNeg);
std::cout << result << std::endl;
// convert to 8bit
result .convertTo(result , CV_8UC1);
std::cout << "the final result:" << std::endl;
std::cout << temp << std::endl;
And the outputs:
original mat
[0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02;
0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002;
0.0002, 0.0002, 0.0002, 0.0002, 0.0002, 0.0002, 0.0002, 0.0002, 0.0002, 0.0002;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
min=0.0002
the calculated min-max
[2.55, 2.55, 2.55, 2.55, 2.55, 2.55, 2.55, 2.55, 2.55, 2.55;
25.5, 25.5, 25.5, 25.5, 25.5, 25.5, 25.5, 25.5, 25.5, 25.5;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
the final result:
[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3;
26, 26, 26, 26, 26, 26, 26, 26, 26, 26;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Yes, It is what I want.

How can I use Lightroom Preset as filter for photos or video in iOS application?

How to apply a filter to an image via GPUImage OR Core Graphics or via any other framework from Lightroom Presets.
How to use Lightroom Presets' element individually on an image (Contrast, Saturation, Tint, Sharpness,etc..).
Individual Lightroom Preset elements:
Unfortunately this isn't an easy task since to use Lightroom presets as filter you need to make an homemade subset of Lightroom.
1: open the preset file with a text editor to investigate on what processing Lightroom use to achieve the effect, is something like
value = {
settings = {
AutoLateralCA = 0,
Blacks2012 = 49,
BlueHue = 11,
BlueSaturation = 4,
CameraProfile = "Adobe Standard",
ChromaticAberrationB = 0,
ChromaticAberrationR = 0,
Clarity2012 = 30,
ColorNoiseReduction = 0,
ColorNoiseReductionDetail = 50,
ColorNoiseReductionSmoothness = 50,
Contrast2012 = 13,
ConvertToGrayscale = true,
CropConstrainToWarp = 0,
Defringe = 0,
DefringeGreenAmount = 0,
DefringeGreenHueHi = 60,
DefringeGreenHueLo = 40,
DefringePurpleAmount = 0,
DefringePurpleHueHi = 70,
DefringePurpleHueLo = 30,
EnableCalibration = true,
EnableCircularGradientBasedCorrections = true,
EnableDetail = true,
EnableEffects = true,
EnableGradientBasedCorrections = true,
EnableGrayscaleMix = true,
EnableLensCorrections = true,
EnableSplitToning = true,
Exposure2012 = 0,
GrainAmount = 0,
GrainFrequency = 50,
GrainSize = 25,
GrayMixerAqua = 4,
GrayMixerBlue = -14,
GrayMixerGreen = -11,
GrayMixerMagenta = 3,
GrayMixerOrange = -3,
GrayMixerPurple = 13,
GrayMixerRed = 8,
GrayMixerYellow = -6,
GreenHue = 26,
GreenSaturation = -1,
Highlights2012 = -9,
LensManualDistortionAmount = 0,
LensProfileEnable = 0,
LensProfileSetup = "LensDefaults",
LuminanceNoiseReductionContrast = 0,
LuminanceNoiseReductionDetail = 50,
LuminanceSmoothing = 0,
ParametricDarks = 8,
ParametricHighlightSplit = 75,
ParametricHighlights = 2,
ParametricLights = 15,
ParametricMidtoneSplit = 50,
ParametricShadowSplit = 25,
ParametricShadows = 9,
PerspectiveAspect = 0,
PerspectiveHorizontal = 0,
PerspectiveRotate = 0,
PerspectiveScale = 100,
PerspectiveUpright = 0,
PerspectiveVertical = 0,
PostCropVignetteAmount = 0,
PostCropVignetteFeather = 50,
PostCropVignetteHighlightContrast = 0,
PostCropVignetteMidpoint = 50,
PostCropVignetteRoundness = 0,
PostCropVignetteStyle = 1,
ProcessVersion = "6.7",
RedHue = 10,
RedSaturation = -5,
ShadowTint = 0,
Shadows2012 = 37,
SharpenDetail = 25,
SharpenEdgeMasking = 0,
SharpenRadius = 1,
Sharpness = 0,
SplitToningBalance = 0,
SplitToningHighlightHue = 0,
SplitToningHighlightSaturation = 0,
SplitToningShadowHue = 0,
SplitToningShadowSaturation = 0,
ToneCurveName2012 = "Black-Mamba_FLP.co",
ToneCurvePV2012 = {
0,
33,
47,
38,
88,
73,
116,
131,
143,
179,
202,
216,
255,
243,
},
ToneCurvePV2012Blue = {
0,
0,
255,
255,
},
ToneCurvePV2012Green = {
0,
0,
255,
255,
},
ToneCurvePV2012Red = {
0,
0,
255,
255,
},
VignetteAmount = -7,
VignetteMidpoint = 46,
WhiteBalance = "As Shot",
Whites2012 = 23,
orientation = "BC",
},
2: Implement all the method that Lightroom use to apply the presets, you can use libraries like this in help
3: you need a method that remap all preset setting as variables and applies the filter

How to understand the math behind the CTM(current transformation matrix)?

When I written some test code about modifying CTM, I found it can't be explain with The Math Behind the Matrices in Quartz 2D Programming Guide. The test code is as follow:
// {a, b, c, d, tx, ty}
NSLog(#"UIKit CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0, CGRectGetHeight(rect));// 1
NSLog(#"Quartz part 1 CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextScaleCTM(ctx, 1, -1);// 2
NSLog(#"Quartz CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextTranslateCTM(ctx, 0, CGRectGetHeight(rect)); // 3
NSLog(#"UIKit part 1 CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextScaleCTM(ctx, 1, -1);// 4
NSLog(#"UIKit part 2 CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextRestoreGState(ctx);
The output:
2017-09-29 09:51:27.166 QuartzDemo[53287:31120880] UIKit CTM:[2, 0, 0, -2, 0, 1136]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] Quartz part 1 CTM:[2, 0, 0, -2, 0, 0]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] Quartz CTM:[2, 0, -0, 2, 0, 0]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] UIKit part 1 CTM:[2, 0, -0, 2, 0, 1136]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] UIKit part 2 CTM:[2, 0, 0, -2, 0, 1136]
First, let's focus on UIKit CTM transforms to Quartz CTM, we use array express matrix, on line 1:
[2, 0, 0, 0, -2, 0, 0, 1136, 1] x [1, 0, 0, 0, 1, 0, tx1, ty1, 1] = [2, 0, 0, 0, -2, 0, 0, 0, 1]
then
[1, 0, 0, 0, 1, 0, tx1, ty1, 1] = [1, 0, 0, 0, 1, 0, -1136, 1]
so in this case CGContextTranslateCTM(ctx, 0, CGRectGetHeight(rect)); equal to [1, 0, 0, 0, 1, 0, -1136, 1], Question 1: Where is minus sign come from?
On line 2:
[2, 0, 0, 0, -2, 0, 0, 0, 1] x [sx1, 0, 0, 0, sy1, 0, 0, 0, 1] = [2, 0, 0, -0, 2, 0, 0, 0, 1]
then
[sx1, 0, 0, 0, sy1, 0, 0, 0, 1] = [1, 0, 0, 0, -1, 0, 0, 0, 1]
so CGContextScaleCTM(ctx, 1, -1); equal to [1, 0, 0, 0, -1, 0, 0, 0, 1], this result is the same as theory value.
On line 3:
[2, 0, 0, -0, 2, 0, 0, 0, 1] x [1, 0, 0, 0, 1, 0, tx2, ty2, 1] = [2, 0, 0, -0, 2, 0, 0, 1136, 1]
then
[1, 0, 0, 0, 1, 0, tx2, ty2, 1] = [2, 0, 0, 0, 2, 0, 0, 1136, 1]
this result also the same as theory value.
On line 4:
[2, 0, 0, 0, 2, 0, 0, 1136, 1] x [sx2, 0, 0, 0, sy2, 0, 0, 0, 1] = [2*sx2, 0, 0, 0, 2*sy2, 0, 0, 1136*sy2, 1]
then
[2*sx2, 0, 0, 0, 2*sy2, 0, 0, 1136*sy2, 1] = [2, 0, 0, 0, -2, 0, 0, 1136, 1]
2*sx2 = 2 => sx2 = 1; but
2*sy2 = -2 (1)
1136*sy2 = 1136 (2)
In equation (1) sy2 = -1, but in equation (2) sy2 = 1, So Question 2: Why this happened? How to explain this case?

Kalman filter 3D implementation

I want to implement the kalman filter for a moving object in r3 (X,Y,Z-coordinate) in OpenCV.
I tried to understand the OpenCV documentation but this is really not helpful and very rare.
The syntax for the initialization is:
KalmanFilter::KalmanFilter ( int dynamParams, int measureParams, int
controlParams = 0, int type = CV_32F )
In my case, is dynamParams = 9 and measureParams=3?
And what is the transitionMatrix in my case?
In that case the Transition Matrix A looks like:
A = [1, 0, 0, v, 0, 0, a, 0, 0;
0, 1, 0, 0, v, 0, 0, a, 0;
0, 0, 1, 0, 0, v, 0, 0, a;
0, 0, 0, 1, 0, 0, v, 0, 0;
0, 0, 0, 0, 1, 0, 0, v, 0;
0, 0, 0, 0, 0, 1, 0, 0, v;
0, 0, 0, 0, 0, 0, 1, 0, 0;
0, 0, 0, 0, 0, 0, 0, 1, 0;
0, 0, 0, 0, 0, 0, 0, 0, 1]
With
v = dt
a = 0.5*dt^2
See http://campar.in.tum.de/Chair/KalmanFilter
I found out, that for the 3D-Case often the position, velocity and acceleration is used. That means, that for the OpenCV implementation dynamParams=9 and measureParams=3 is right.

Resources