OpenCV how to use UsacParams and specify USAC method - opencv

I am using openCV 4.5 and I'm using USAC to find the fundamental matrix. This works fine for specifying a USAC method:
import cv2
a,b = cv2.FindFundamentalMat(pts1, pts2, cv2.USAC_FAST)
and this works fine for specifying USAC parameters:
params = cv2.UsacParams()
params.maxIterations=700
a,b = cv2.FindFundamentalMat(pts1, pts2, params)
But I can't figure out how to specify both the method and the settings. Or does the method determine the settings?

Looking into the C++ source code, we can see that the two different ways of calling the function (with or without the UsacParams) lead to different calls to setParameters.
In conclusion, you're right that the choice of method (e.g. USAC_FAST) determines the settings (at least in C++ code).
From https://github.com/opencv/opencv/blob/4.x/modules/calib3d/src/usac/ransac_solvers.cpp
If you pass UsacParams:
void setParameters (Ptr<Model> &params, EstimationMethod estimator, const UsacParams &usac_params, bool mask_needed) {
params = Model::create(usac_params.threshold, estimator, usac_params.sampler, usac_params.confidence, usac_params.maxIterations, usac_params.score);
params->setLocalOptimization(usac_params.loMethod);
params->setLOSampleSize(usac_params.loSampleSize);
params->setLOIterations(usac_params.loIterations);
params->setParallel(usac_params.isParallel);
params->setNeighborsType(usac_params.neighborsSearch);
params->setRandomGeneratorState(usac_params.randomGeneratorState);
params->maskRequired(mask_needed);
}
If you pass a method instead of UsacParams:
void setParameters (int flag, Ptr<Model> &params, EstimationMethod estimator, double thr,
int max_iters, double conf, bool mask_needed) {
switch (flag) {
case USAC_DEFAULT:
params = Model::create(thr, estimator, SamplingMethod::SAMPLING_UNIFORM, conf, max_iters, ScoreMethod::SCORE_METHOD_MSAC);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_INNER_AND_ITER_LO);
break;
case USAC_MAGSAC:
params = Model::create(thr, estimator, SamplingMethod::SAMPLING_UNIFORM, conf, max_iters, ScoreMethod::SCORE_METHOD_MAGSAC);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_SIGMA);
params->setLOSampleSize(params->isHomography() ? 75 : 50);
params->setLOIterations(params->isHomography() ? 15 : 10);
break;
case USAC_PARALLEL:
params = Model::create(thr, estimator, SamplingMethod::SAMPLING_UNIFORM, conf, max_iters, ScoreMethod::SCORE_METHOD_MSAC);
params->setParallel(true);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_INNER_LO);
break;
case USAC_ACCURATE:
params = Model::create(thr, estimator, SamplingMethod::SAMPLING_UNIFORM, conf, max_iters, ScoreMethod::SCORE_METHOD_MSAC);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_GC);
params->setLOSampleSize(20);
params->setLOIterations(25);
break;
case USAC_FAST:
params = Model::create(thr, estimator, SamplingMethod::SAMPLING_UNIFORM, conf, max_iters, ScoreMethod::SCORE_METHOD_MSAC);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_INNER_AND_ITER_LO);
params->setLOIterations(5);
params->setLOIterativeIters(3);
break;
case USAC_PROSAC:
params = Model::create(thr, estimator, SamplingMethod::SAMPLING_PROSAC, conf, max_iters, ScoreMethod::SCORE_METHOD_MSAC);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_INNER_LO);
break;
case USAC_FM_8PTS:
params = Model::create(thr, EstimationMethod::Fundamental8,SamplingMethod::SAMPLING_UNIFORM, conf, max_iters,ScoreMethod::SCORE_METHOD_MSAC);
params->setLocalOptimization(LocalOptimMethod ::LOCAL_OPTIM_INNER_LO);
break;
default: CV_Error(cv::Error::StsBadFlag, "Incorrect flag for USAC!");
}
// do not do too many iterations for PnP
if (estimator == EstimationMethod::P3P) {
if (params->getLOInnerMaxIters() > 15)
params->setLOIterations(15);
params->setLOIterativeIters(0);
}
params->maskRequired(mask_needed);
}
For more information, check out the descriptions of the different parameters here: https://docs.opencv.org/4.5.0/d1/df1/md__build_master-contrib_docs-lin64_opencv_doc_tutorials_calib3d_usac.html

Related

Esp32 LoRa lmic TTN not connecting

I am trying to get my ESP32 + RFM95C connected to The Things Network.
The Error I recieve is simple this:
24951: EV_JOINING
24970: EV_TXSTART
426696: EV_JOIN_TXCOMPLETE: no JoinAccept
And that repeats, Here is my setup code:
static const u1_t PROGMEM APPEUI[8]= { secret stuff here };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
// This should also be in little endian format, see above.
// static const u1_t PROGMEM DEVEUI[8]= { secret stuff here };
static const u1_t PROGMEM DEVEUI[8]= { secret stuff here };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
static const u1_t PROGMEM APPKEY[16] = { secret stuff here };
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
static uint8_t mydata[] = "Hello, world!";
static osjob_t sendjob;
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 60;
// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 5,
.rxtx = LMIC_UNUSED_PIN,
.rst = 27,
.dio = {2, 26, 25},
};
void printHex2(unsigned v) {
v &= 0xff;
if (v < 16)
Serial.print('0');
Serial.print(v, HEX);
}
void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
{
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print("netid: ");
Serial.println(netid, DEC);
Serial.print("devaddr: ");
Serial.println(devaddr, HEX);
Serial.print("AppSKey: ");
for (size_t i=0; i<sizeof(artKey); ++i) {
if (i != 0)
Serial.print("-");
printHex2(artKey[i]);
}
Serial.println("");
Serial.print("NwkSKey: ");
for (size_t i=0; i<sizeof(nwkKey); ++i) {
if (i != 0)
Serial.print("-");
printHex2(nwkKey[i]);
}
Serial.println();
}
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.print(F("Received "));
Serial.print(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
//Now we sleep
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
esp_deep_sleep_start();
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
case EV_TXCANCELED:
Serial.println(F("EV_TXCANCELED"));
break;
case EV_RXSTART:
/* do not print anything -- it wrecks timing */
break;
case EV_JOIN_TXCOMPLETE:
Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
}
}
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
Nothing all that special, just boilerplate sketch code.
I have a Dragino LPS8 LoRaWan Gateway with these settings:
Does anyone know why my connection will not go through?
It has been a while, and I have learned a LOT more about LoRaWan since I originally posted this question. I now know that OTAA will not work with a single channel gateway such as the dragino I had shown in the pictures. A gateway such as https://www.adafruit.com/product/4345 (an 8 channel gateway) would have been a better place for me to start this project.

RSS (Receive Side Scaling) on Intel XL710 Per port

I struggle with Intel XL710 card using DPDK to make it compute RSS hash using only SRC IPV4 or DST IPV4 on per port basis.
The card has 4 10GE ports and RSS config is global for them whatever i do. I tried to set SRC/DST IPV4 fields in PCTYPE and the configuration applied last only takes action.
So the behavior i want to achieve.
Let's say i have upstream packet arrived on port 0:
SRC: 10.10.10.1 and DST:10.10.10.2
And reply downstream packet arrived on port 1:
SRC: 10.10.10.2 and DST:10.10.10.1
I want port 0 (which in our case is upstream) on the card to compute RSS hash based on SRC address 10.10.10.1 and for, port 1 (which is downstream) to compute the hash using DST address which in our case also will be 10.10.10.1. So the idea is to distribute packets between RX queues in a way that only SRC/DST address respectively affects this distribution.
I'm not bound specifically to RSS. Whatever tech will do if it allows to achieve this.
The configuration i used:
void setFilter(uint16_t portId, uint32_t value){
//Value = RTE_ETH_FLOW_NONFRAG_IPV4_TCP in that case
struct rte_eth_hash_filter_info info;
uint32_t ftype, idx, offset;
int ret;
if (rte_eth_dev_filter_supported(portId,
RTE_ETH_FILTER_HASH) < 0) {
printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
portId);
return;
}
memset(&info, 0, sizeof(info));
info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
info.info.global_conf.hash_func =
RTE_ETH_HASH_FUNCTION_DEFAULT;
ftype = value;
idx = ftype / UINT64_BIT;
offset = ftype % UINT64_BIT;
info.info.global_conf.valid_bit_mask[idx] |= (1ULL << offset);
info.info.global_conf.sym_hash_enable_mask[idx] |=
(1ULL << offset);
ret = rte_eth_dev_filter_ctrl(portId, RTE_ETH_FILTER_HASH,
RTE_ETH_FILTER_SET, &info);
if (ret < 0)
printf("Cannot set global hash configurations by port %d\n",
portId);
else
printf("Global hash configurations have been set "
"succcessfully by port %d\n", portId);
}
void setPctypeRss(uint16_t portId, uint16_t fieldIdx) {
/* Note that AVF_FILTER_PCTYPE_NONF_IPV4_TCP is define for
* Virtual Function. Defines are the same for Physical Functions
*/
int ret = -ENOTSUP;
enum rte_pmd_i40e_inset_type inset_type = INSET_HASH;
struct rte_pmd_i40e_inset inset;
ret = rte_pmd_i40e_inset_get(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to get input set.\n");
return;
}
memset(&inset, 0, sizeof(inset));
ret = rte_pmd_i40e_inset_set(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to CLEAR input set.\n");
return;
}
else
{
printf("Successfull cleared input set\n");
}
ret = rte_pmd_i40e_inset_get(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to get input set.\n");
return;
}
ret = rte_pmd_i40e_inset_field_set(&inset.inset, fieldIdx);
if (ret) {
printf("Failed to configure input set field.\n");
return;
}
ret = rte_pmd_i40e_inset_set(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to set input set.\n");
return;
}
if (ret == -ENOTSUP)
printf("Function not supported\n");
}
IMO it is worth trying a bit simpler solution. We can simply use rte_eth_dev_configure():
https://doc.dpdk.org/api/rte__ethdev_8h.html#a1a7d3a20b102fee222541fda50fd87bd
And just set eth_conf.rss_conf.rss_hf to ETH_RSS_IP as described here:
https://doc.dpdk.org/api/structrte__eth__rss__conf.html#ad70f17882a835e5d4e38c64a9f872fdc
There are few examples in DPDK using this functionality. and most of them work fine ;)

PIC32MZ2048ECH144 USART- Junk characters transmitted

I am new to MPLAB X Harmony framework and also in working with microcontrollers. I am working on PIC32MZ2048ECH144. I wanted to transmit a simple string using USART and see it displayed in RealTerm terminal.(I have tried HyperTerminal also.) Whatever string I send, I see only junk characters being displayed. When I browsed for the solution for this problem of junk characters being displayed, there were suggestions to check for the baud rate. I have set the baud rate to be 9600 in MPLab Harmony Configurator(Options -> Harmony Framework configuration -> Drivers -> USART -> USART Driver Instance 0 -> Baud Rate -> 9600). So I used the following line in app.c to explicitly set the baud rate.(PBCLK is 100MHz). But no luck!
PLIB_USART_BaudRateSet(USART_ID_2, 100000000 ,9600);
The code for app.c file:
/*******************************************************************************
Start of File
*/
const char *string1 = "*** UART Interrupt-driven Application Example ***\r\n";
const char *string2 = "*** Type some characters and observe the LED turn ON ***\r\n";
APP_DATA appData =
{
};
APP_DRV_OBJECTS appDrvObject;
void APP_Initialize ( void )
{
appData.state = USART_ENABLE;
appData.InterruptFlag = false;
}
bool WriteString(void)
{
if(*appData.stringPointer == '\0')
{
return true;
}
while (PLIB_USART_TransmitterIsEmpty(USART_ID_1))
{
PLIB_USART_TransmitterByteSend(USART_ID_1, *appData.stringPointer);
appData.stringPointer++;
if(*appData.stringPointer == '\0')
{
return true;
}
}
return false;
}
bool PutCharacter(const char character)
{
if(PLIB_USART_TransmitterIsEmpty(USART_ID_1))
{
PLIB_USART_TransmitterByteSend(USART_ID_1, character);
return true;
}
else
return false;
}
void APP_Tasks ( void )
{
/* check the application state*/
switch ( appData.state )
{
case USART_ENABLE:
/* Enable the UART module*/
PLIB_USART_BaudRateSet(USART_ID_1, 100000000 ,9600);
PLIB_USART_Enable(USART_ID_1);
appData.stringPointer = string1;
appData.state = USART_TRANSMIT_FIRST_STRING;
break;
case USART_TRANSMIT_FIRST_STRING:
if(true == WriteString())
{
appData.state = USART_TRANSMIT_SECOND_STRING;
appData.stringPointer = string2;
}
break;
case USART_TRANSMIT_SECOND_STRING:
if(true == WriteString())
{
appData.state = USART_RECEIVE_DONE;
}
break;
case USART_RECEIVE_DONE:
if (appData.InterruptFlag)
{
if(true == PutCharacter(appData.data))
{
appData.InterruptFlag = false;
}
}
break;
default:
while (1);
}
}
/*******************************************************************************
End of File
*/
I am sorry that I cannot attach the image of the output I receive in RealTerm as I do not have enough points.
I have no clue where else the problem could be that gives the mismatch of baud rate. Any hints or help would be of great help. Thanks in advance.
Kindly apologize me for any mistakes in the post.
you are correct that it is most likely BAUD rate, but just to be sure how is the USART hooked to the computer? Do you have a translator chip since the computer is expecting +-5V? As for the BAUD, check your clocking scheme and know that PBCLK is sometimes DIV_2 of the SYSCLOCK. There is a great clocking schematic in the Harmony framework to double check your clocking and CONFIG pragmas.

Javascript minification logic where immutable properties are involved

A question on the minifying logic.
// Assumptions:
//com.example.dummy ns is available
//com.example.dummy.type is defined immutable -> Object.defineProperty
var test, test1, test2;
function execute_case(id) {
switch(id) {
case 0:
test = com.example.dummy.type;
break;
case 1:
test1 = com.example.dummy.type;
break;
case 2:
test2 = com.example.dummy.type;
break;
default:
console.log("default");
break;
}
}
the YUI compressor compresses it to,
var test,test1,test2;function execute_case(a){switch(a){case 0:
test=com.example.dummy.type;break;case 1:test1=com.example.dummy.type;break;
case 2:test2=com.example.dummy.type;break;default:console.log("default");break}};
Wouldn't it be logical for the compressor do the following as an optimization?
var test, test1, test2;
var st = com.example.dummy.type;
function execute_case(id) {
switch(id) {
case 0:
test = st;
case 1:
test1 = st;
break;
case 2:
test2 = st;
break;
default:
console.log("default");
break;
}
}
As can be seen, the compression here works out better.
var test,test1,test2;var st=com.example.dummy.type;function execute_case(a){
switch(a){case 0:test=st;case 1:test1=st;break;case 2:test2=st;break;
default:console.log("default");break}};
That optimization makes sense for uncompressed source code, but not if the file is delivered with gzip compression (which is highly recommended).
String aliasing tends to make the compressed source code larger.
See the Closure-compiler FAQ

Assimp not properly loading indices

I'm trying to load simple 3d model cube.3ds, but next error occurs: when I read indices to my vector, vector contains: [0, 1, 2, 3, ...]. It's not properly. I found almost the same topic: Assimp and D3D model loading: Mesh not being displayed in D3D, but I don't found the answer. Can anyone describe in detail properly algorithm for loading indices from meshes. Thank's a lot!
Here is a example pulled from the assimp sample code on accessing the mesh indices.
for (; n < nd->mNumMeshes; ++n)
{
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
if(mesh->mNormals == NULL) {
glDisable(GL_LIGHTING);
} else {
glEnable(GL_LIGHTING);
}
for (t = 0; t < mesh->mNumFaces; ++t) {
const struct aiFace* face = &mesh->mFaces[t];
GLenum face_mode;
switch(face->mNumIndices) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
for(i = 0; i < face->mNumIndices; i++) {
int index = face->mIndices[i];
if(mesh->mColors[0] != NULL)
glColor4fv((GLfloat*)&mesh->mColors[0][index]);
if(mesh->mNormals != NULL)
glNormal3fv(&mesh->mNormals[index].x);
glVertex3fv(&mesh->mVertices[index].x);
}
glEnd();
}
}

Resources