NvBool NvRmPrivAp20DttClockUpdate( NvRmDeviceHandle hRmDevice, const NvRmTzonePolicy* pDttPolicy, const NvRmDfsFrequencies* pCurrentKHz, NvRmDfsFrequencies* pDfsKHz) { switch ((NvRmDttAp20PolicyRange)pDttPolicy->PolicyRange) { case NvRmDttAp20PolicyRange_ThrottleDown: if (pDttPolicy->UpdateFlag) s_CpuThrottleKHz -= NVRM_DTT_CPU_DELTA_KHZ; s_CpuThrottleKHz = NV_MAX(s_CpuThrottleKHz, s_CpuThrottleMinKHz); break; // No throttling by default (just reset throttling limit to max) default: s_CpuThrottleKHz = s_CpuThrottleMaxKHz; return NV_FALSE; } pDfsKHz->Domains[NvRmDfsClockId_Cpu] = NV_MIN(pDfsKHz->Domains[NvRmDfsClockId_Cpu], s_CpuThrottleKHz); // Throttling step is completed - no need to force extra DVFS update return NV_FALSE; }
/** * Write into the transmit fifo register. * returns the number of words written. */ static NvU32 SlinkHwWriteInTransmitFifo( SerialHwRegisters *pSlinkHwRegs, NvU32 *pTxBuff, NvU32 WordRequested) { NvU32 WordWritten = 0; NvU32 WordsRemaining = NV_MIN(WordRequested, MAX_SLINK_FIFO_DEPTH); while (WordsRemaining) { SLINK_REG_WRITE32(pSlinkHwRegs->pRegsBaseAdd, TX_FIFO, *pTxBuff); pTxBuff++; WordsRemaining--; WordWritten++; } return WordWritten; }
void patch_sampling(nv_matrix_t *samples, std::vector<fileinfo_t> &list) { nv_matrix_t *data = nv_matrix_alloc(PATCH_SIZE * PATCH_SIZE * 3, (int)((IMG_SIZE-PATCH_SIZE) * (IMG_SIZE-PATCH_SIZE) * list.size())); int data_index = 0; int i; nv_matrix_zero(data); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 1) #endif for (i = 0; i < (int)list.size(); ++i) { nv_matrix_t *src; nv_matrix_t *patches; src = nv_load_image(list[i].file.c_str()); if (!src) { fprintf(stderr, "open filed: %s\n", list[i].file.c_str()); exit(-1); } patches = nv_patch_matrix_alloc(src, PATCH_SIZE); nv_patch_extract(patches, src, PATCH_SIZE); #ifdef _OPENMP #pragma omp critical (patch_sampling) #endif { int j; for (j = 0; j < patches->m; ++j) { nv_vector_copy(data, data_index, patches, j); data_index += 1; } } nv_matrix_free(&src); nv_matrix_free(&patches); } nv_vector_shuffle(data); nv_matrix_m(data, NV_MIN(samples->m, data_index)); nv_matrix_copy_all(samples, data); nv_matrix_free(&data); }
void nv_histgram_equalization(nv_matrix_t *eq, const nv_matrix_t *img, int channel) { float freq[256] = {0}; float fm; int m, i; float min_freq = FLT_MAX; NV_ASSERT(eq->m == img->m); if (img->m == 0) { nv_matrix_zero(eq); return ; } // freq fm = 1.0f / (float )img->m; for (m = 0; m < img->m; ++m) { int idx = (int)NV_MAT_V(img, m, channel); freq[idx] += 1.0f; } for (i = 1; i < 256; ++i) { freq[i] = freq[i] + freq[i - 1]; } for (i = 0; i < 256; ++i) { freq[i] *= fm; if (freq[i] < min_freq) { min_freq = freq[i]; } } if (min_freq == 1.0) { min_freq = 0.999999f; } // equalization for (m = 0; m < img->m; ++m) { int idx = (int)NV_MAT_V(img, m, channel); float v = (freq[idx] - min_freq) * 255.0f / (1.0f - min_freq);//255.0f * freq[idx]; v = NV_MIN(NV_MAX(v, 0.0f), 255.0f); NV_MAT_V(eq, m, channel) = v; } }
void NvRmPrivAp20DttPolicyUpdate( NvRmDeviceHandle hRmDevice, NvRmDtt* pDtt) { NvBool Throttle = NvOdmTmonThrottle(pDtt->hOdmTcore); // CPU throttling limits are set at 50% of CPU frequency range (no // throttling below this value), and at CPU frequency boundary that // matches specified voltage throttling limit. if ((!s_CpuThrottleMaxKHz) || (!s_CpuThrottleMinKHz)) { NvU32 steps; const NvRmFreqKHz* p = NvRmPrivModuleVscaleGetMaxKHzList( hRmDevice, NvRmModuleID_Cpu, &steps); NV_ASSERT(p && steps); for (; steps != 0 ; steps--) { if (NVRM_DTT_VOLTAGE_THROTTLE_MV >= NvRmPrivModuleVscaleGetMV( hRmDevice, NvRmModuleID_Cpu, p[steps-1])) break; } NV_ASSERT(steps); s_CpuThrottleMaxKHz = NV_MIN( NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz, p[steps-1]); s_CpuThrottleMinKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz / NVRM_DTT_RATIO_MAX; NV_ASSERT(s_CpuThrottleMaxKHz > s_CpuThrottleMinKHz); NV_ASSERT(s_CpuThrottleMinKHz > NVRM_DTT_CPU_DELTA_KHZ); s_CpuThrottleKHz = s_CpuThrottleMaxKHz; } pDtt->TcorePolicy.PolicyRange = Throttle ? NvRmDttAp20PolicyRange_ThrottleDown : NvRmDttAp20PolicyRange_FreeRunning; pDtt->TcorePolicy.UpdateIntervalUs = Throttle ? NVRM_DTT_POLL_MS_CRITICAL * 1000 : NV_WAIT_INFINITE; }
const NvRmModuleClockLimits* NvRmPrivClockLimitsInit(NvRmDeviceHandle hRmDevice) { NvU32 i; NvRmFreqKHz CpuMaxKHz, AvpMaxKHz, VdeMaxKHz, TDMaxKHz, DispMaxKHz; NvRmSKUedLimits* pSKUedLimits; const NvRmScaledClkLimits* pHwLimits; const NvRmSocShmoo* pShmoo; NV_ASSERT(hRmDevice); NvRmPrivChipFlavorInit(hRmDevice); pShmoo = s_ChipFlavor.pSocShmoo; pHwLimits = &pShmoo->ScaledLimitsList[0]; #ifndef CONFIG_FAKE_SHMOO pSKUedLimits = pShmoo->pSKUedLimits; #else /* NvRmFreqKHz CpuMaxKHz; NvRmFreqKHz AvpMaxKHz; NvRmFreqKHz VdeMaxKHz; NvRmFreqKHz McMaxKHz; NvRmFreqKHz Emc2xMaxKHz; NvRmFreqKHz TDMaxKHz; NvRmFreqKHz DisplayAPixelMaxKHz; NvRmFreqKHz DisplayBPixelMaxKHz; NvRmMilliVolts NominalCoreMv; // for common core rail NvRmMilliVolts NominalCpuMv; // for dedicated CPU rail */ pSKUedLimits = pShmoo->pSKUedLimits; // override default with configuration values // CPU clock duh! pSKUedLimits->CpuMaxKHz = MAX_CPU_OC_FREQ; #ifdef CONFIG_BOOST_PERIPHERALS // AVP clock pSKUedLimits->AvpMaxKHz = CONFIG_MAX_AVP_OC_FREQ; // 3D clock pSKUedLimits->TDMaxKHz = CONFIG_MAX_3D_OC_FREQ; #endif // CONFIG_BOOST_PERIPHERALS #endif // CONFIG_FAKE_SHMOO NvOsDebugPrintf("NVRM corner (%d, %d)\n", s_ChipFlavor.corner, s_ChipFlavor.CpuCorner); NvOsMemset((void*)s_pClockScales, 0, sizeof(s_pClockScales)); NvOsMemset(s_ClockRangeLimits, 0, sizeof(s_ClockRangeLimits)); NvOsMemset(s_VoltageStepRefCounts, 0, sizeof(s_VoltageStepRefCounts)); s_VoltageStepRefCounts[0] = NvRmPrivModuleID_Num; // all at minimum step // Combine AVP/System clock absolute limit with scaling V/F ladder upper // boundary, and set default clock range for all present modules the same // as for AVP/System clock #ifdef CONFIG_AVP_OVERCLOCK AvpMaxKHz = 266400; #else AvpMaxKHz = pSKUedLimits->AvpMaxKHz; for (i = 0; i < pShmoo->ScaledLimitsListSize; i++) { if (pHwLimits[i].HwDeviceId == NV_DEVID_AVP) { AvpMaxKHz = NV_MIN( AvpMaxKHz, pHwLimits[i].MaxKHzList[pShmoo->ShmooVmaxIndex]); break; } } #endif //CONFIG_AVP_OVERCLOCK for (i = 0; i < NvRmPrivModuleID_Num; i++) { NvRmModuleInstance *inst; if (NvRmPrivGetModuleInstance(hRmDevice, i, &inst) == NvSuccess) { s_ClockRangeLimits[i].MaxKHz = AvpMaxKHz; s_ClockRangeLimits[i].MinKHz = NVRM_BUS_MIN_KHZ; } } // Fill in limits for modules with slectable clock sources and/or dividers // as specified by the h/w table according to the h/w device ID // (CPU and AVP are not in relocation table - need translate id explicitly) // TODO: need separate subclock limits? (current implementation applies // main clock limits to all subclocks) for (i = 0; i < pShmoo->ScaledLimitsListSize; i++) { NvRmModuleID id; if (pHwLimits[i].HwDeviceId == NV_DEVID_CPU) id = NvRmModuleID_Cpu; else if (pHwLimits[i].HwDeviceId == NV_DEVID_AVP) id = NvRmModuleID_Avp; else if (pHwLimits[i].HwDeviceId == NVRM_DEVID_CLK_SRC) id = NvRmClkLimitsExtID_ClkSrc; else id = NvRmPrivDevToModuleID(pHwLimits[i].HwDeviceId); if ((id != NVRM_DEVICE_UNKNOWN) && (pHwLimits[i].SubClockId == 0)) { s_ClockRangeLimits[id].MinKHz = pHwLimits[i].MinKHz; s_ClockRangeLimits[id].MaxKHz = pHwLimits[i].MaxKHzList[pShmoo->ShmooVmaxIndex]; s_pClockScales[id] = pHwLimits[i].MaxKHzList; } } // Fill in CPU scaling data if SoC has dedicated CPU rail, and CPU clock // characterization data is separated from other modules on common core rail if (s_ChipFlavor.pCpuShmoo) { const NvRmScaledClkLimits* pCpuLimits = s_ChipFlavor.pCpuShmoo->pScaledCpuLimits; NV_ASSERT(pCpuLimits && (pCpuLimits->HwDeviceId == NV_DEVID_CPU)); s_ClockRangeLimits[NvRmModuleID_Cpu].MinKHz = pCpuLimits->MinKHz; s_ClockRangeLimits[NvRmModuleID_Cpu].MaxKHz = pCpuLimits->MaxKHzList[s_ChipFlavor.pCpuShmoo->ShmooVmaxIndex]; s_pClockScales[NvRmModuleID_Cpu] = pCpuLimits->MaxKHzList; } // Set AVP upper clock boundary with combined Absolute/Scaled limit; // Sync System clock with AVP (System is not in relocation table) s_ClockRangeLimits[NvRmModuleID_Avp].MaxKHz = AvpMaxKHz; s_ClockRangeLimits[NvRmPrivModuleID_System].MaxKHz = s_ClockRangeLimits[NvRmModuleID_Avp].MaxKHz; s_ClockRangeLimits[NvRmPrivModuleID_System].MinKHz = s_ClockRangeLimits[NvRmModuleID_Avp].MinKHz; s_pClockScales[NvRmPrivModuleID_System] = s_pClockScales[NvRmModuleID_Avp]; // Set VDE upper clock boundary with combined Absolute/Scaled limit (on // AP15/Ap16 VDE clock derived from the system bus, and VDE maximum limit // must be the same as AVP/System). VdeMaxKHz = pSKUedLimits->VdeMaxKHz; VdeMaxKHz = NV_MIN( VdeMaxKHz, s_ClockRangeLimits[NvRmModuleID_Vde].MaxKHz); if ((hRmDevice->ChipId.Id == 0x15) || (hRmDevice->ChipId.Id == 0x16)) { NV_ASSERT(VdeMaxKHz == AvpMaxKHz); } s_ClockRangeLimits[NvRmModuleID_Vde].MaxKHz = VdeMaxKHz; // Set upper clock boundaries for devices on CPU bus (CPU, Mselect, // CMC) with combined Absolute/Scaled limits CpuMaxKHz = pSKUedLimits->CpuMaxKHz; CpuMaxKHz = NV_MIN( CpuMaxKHz, s_ClockRangeLimits[NvRmModuleID_Cpu].MaxKHz); s_ClockRangeLimits[NvRmModuleID_Cpu].MaxKHz = CpuMaxKHz; if ((hRmDevice->ChipId.Id == 0x15) || (hRmDevice->ChipId.Id == 0x16)) { s_ClockRangeLimits[NvRmModuleID_CacheMemCtrl].MaxKHz = CpuMaxKHz; s_ClockRangeLimits[NvRmPrivModuleID_Mselect].MaxKHz = CpuMaxKHz; NV_ASSERT(s_ClockRangeLimits[NvRmClkLimitsExtID_ClkSrc].MaxKHz >= CpuMaxKHz); } else if (hRmDevice->ChipId.Id == 0x20) { // No CMC; TODO: Mselect/CPU <= 1/4? s_ClockRangeLimits[NvRmPrivModuleID_Mselect].MaxKHz = CpuMaxKHz >> 2; }
static gboolean ctk_banner_configure_event( GtkWidget *widget, GdkEventConfigure *event ) { CtkBanner *ctk_banner = CTK_BANNER(widget); int x, y, w, h, needed_w, needed_h; /* free the pixbuf we already have one */ if (ctk_banner->back.pixbuf) g_object_unref(ctk_banner->back.pixbuf); /* allocate a backing pixbuf the size of the new window */ ctk_banner->back.pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, // colorSpace FALSE, // has_alpha (no alpha needed for backing pixbuf) gdk_pixbuf_get_bits_per_sample (ctk_banner->background->pixbuf), event->width, event->height); ctk_banner->back.w = gdk_pixbuf_get_width(ctk_banner->back.pixbuf); ctk_banner->back.h = gdk_pixbuf_get_height(ctk_banner->back.pixbuf); /* clear the backing pixbuf to black */ gdk_pixbuf_fill(ctk_banner->back.pixbuf, 0x00000000); /* copy the base image into the backing pixbuf */ w = NV_MIN(ctk_banner->background->w, ctk_banner->back.w); h = NV_MIN(ctk_banner->background->h, ctk_banner->back.h); gdk_pixbuf_copy_area(ctk_banner->background->pixbuf, // src 0, // src_x 0, // src_y w, // width h, // height ctk_banner->back.pixbuf, // dest 0, // dest_x 0); // dest_y /* * composite the logo into the backing pixbuf; positioned in the * upper right corner of the backing pixbuf. We should only do * this, though, if the backing pixbuf is large enough to contain * the logo */ needed_w = ctk_banner->logo->w + ctk_banner->logo_pad_x; needed_h = ctk_banner->logo->h + ctk_banner->logo_pad_y; if ((ctk_banner->back.w >= needed_w) && (ctk_banner->back.h >= needed_h)) { w = ctk_banner->logo->w; h = ctk_banner->logo->h; x = ctk_banner->back.w - w; y = 0; ctk_banner->logo_x = x - ctk_banner->logo_pad_x; ctk_banner->logo_y = y + ctk_banner->logo_pad_y; gdk_pixbuf_composite(ctk_banner->logo->pixbuf, // src ctk_banner->back.pixbuf, // dest ctk_banner->logo_x, // dest_x ctk_banner->logo_y, // dest_y w, // dest_width h, // dest_height ctk_banner->logo_x, // offset_x ctk_banner->logo_y, // offset_y 1.0, // scale_x 1.0, // scale_y GDK_INTERP_BILINEAR, // interp_type 255); // overall_alpha } /* * composite the artwork into the lower left corner of the backing * pixbuf */ needed_w = ctk_banner->artwork.w + ctk_banner->artwork_pad_x; needed_h = ctk_banner->artwork.h; if ((ctk_banner->back.w >= needed_w) && (ctk_banner->back.h >= needed_h)) { w = ctk_banner->artwork.w; h = ctk_banner->artwork.h; x = 0; y = ctk_banner->back.h - h; ctk_banner->artwork_x = x + ctk_banner->artwork_pad_x; ctk_banner->artwork_y = y; gdk_pixbuf_composite(ctk_banner->artwork.pixbuf, // src ctk_banner->back.pixbuf, // dest ctk_banner->artwork_x, // dest_x ctk_banner->artwork_y, // dest_y w, // dest_width h, // dest_height ctk_banner->artwork_x, // offset_x ctk_banner->artwork_y, // offset_y 1.0, // scale_x 1.0, // scale_y GDK_INTERP_BILINEAR, // interp_type 255); // overall_alpha /* Do any user-specific compositing */ if (ctk_banner->callback_func) { ctk_banner->callback_func(ctk_banner, ctk_banner->callback_data); } } return FALSE; }
void NvRmPrivAp20DttPolicyUpdate( NvRmDeviceHandle hRmDevice, NvS32 TemperatureC, NvRmDtt* pDtt) { NvRmDttAp20PolicyRange Range; // CPU throttling limits are set at 50% of CPU frequency range (no // throttling below this value), and at CPU frequency boundary that // matches specified voltage throttling limit. if ((!s_CpuThrottleMaxKHz) || (!s_CpuThrottleMinKHz)) { NvU32 steps; const NvRmFreqKHz* p = NvRmPrivModuleVscaleGetMaxKHzList( hRmDevice, NvRmModuleID_Cpu, &steps); NV_ASSERT(p && steps); for (; steps != 0 ; steps--) { if (NVRM_DTT_VOLTAGE_THROTTLE_MV >= NvRmPrivModuleVscaleGetMV( hRmDevice, NvRmModuleID_Cpu, p[steps-1])) break; } NV_ASSERT(steps); s_CpuThrottleMaxKHz = NV_MIN( NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz, p[steps-1]); s_CpuThrottleMinKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz / NVRM_DTT_RATIO_MAX; NV_ASSERT(s_CpuThrottleMaxKHz > s_CpuThrottleMinKHz); NV_ASSERT(s_CpuThrottleMinKHz > NVRM_DTT_CPU_DELTA_KHZ); s_CpuThrottleKHz = s_CpuThrottleMaxKHz; NV_ASSERT(pDtt->TcoreCaps.Tmin < (NVRM_DTT_DEGREES_LOW - NVRM_DTT_DEGREES_HYSTERESIS)); NV_ASSERT(pDtt->TcoreCaps.Tmax > NVRM_DTT_DEGREES_HIGH); } // Advanced policy range state machine (one step at a time) Range = (NvRmDttAp20PolicyRange)pDtt->TcorePolicy.PolicyRange; switch (Range) { case NvRmDttAp20PolicyRange_Unknown: Range = NvRmDttAp20PolicyRange_FreeRunning; // fall through case NvRmDttAp20PolicyRange_FreeRunning: if (TemperatureC >= NVRM_DTT_DEGREES_LOW) Range = NvRmDttAp20PolicyRange_LimitVoltage; break; case NvRmDttAp20PolicyRange_LimitVoltage: if (TemperatureC <= (NVRM_DTT_DEGREES_LOW - NVRM_DTT_DEGREES_HYSTERESIS)) Range = NvRmDttAp20PolicyRange_FreeRunning; else if (TemperatureC >= NVRM_DTT_DEGREES_HIGH) Range = NvRmDttAp20PolicyRange_ThrottleDown; break; case NvRmDttAp20PolicyRange_ThrottleDown: if (TemperatureC <= (NVRM_DTT_DEGREES_HIGH - NVRM_DTT_DEGREES_HYSTERESIS)) Range = NvRmDttAp20PolicyRange_LimitVoltage; break; default: break; } /* * Fill in new policy. Temperature limits are set around current * temperature for the next out-of-limit interrupt (possible exception * - temperature "jump" over two ranges would result in two interrupts * in a row before limits cover the temperature). Polling time is set * always in ThrottleDown range, and only for poll mode in other ranges. */ pDtt->CoreTemperatureC = TemperatureC; switch (Range) { case NvRmDttAp20PolicyRange_FreeRunning: pDtt->TcorePolicy.LowLimit = pDtt->TcoreLowLimitCaps.MinValue; pDtt->TcorePolicy.HighLimit = NVRM_DTT_DEGREES_LOW; pDtt->TcorePolicy.UpdateIntervalUs = pDtt->UseIntr ? NV_WAIT_INFINITE : (NVRM_DTT_POLL_MS_SLOW * 1000); break; case NvRmDttAp20PolicyRange_LimitVoltage: pDtt->TcorePolicy.LowLimit = NVRM_DTT_DEGREES_LOW - NVRM_DTT_DEGREES_HYSTERESIS; pDtt->TcorePolicy.HighLimit = NVRM_DTT_DEGREES_HIGH; pDtt->TcorePolicy.UpdateIntervalUs = pDtt->UseIntr ? NV_WAIT_INFINITE : (NVRM_DTT_POLL_MS_FAST * 1000); break; case NvRmDttAp20PolicyRange_ThrottleDown: pDtt->TcorePolicy.LowLimit = NVRM_DTT_DEGREES_HIGH - NVRM_DTT_DEGREES_HYSTERESIS; pDtt->TcorePolicy.HighLimit = pDtt->TcoreHighLimitCaps.MaxValue; pDtt->TcorePolicy.UpdateIntervalUs = NVRM_DTT_POLL_MS_CRITICAL * 1000; break; default: NV_ASSERT(!"Invalid DTT policy range"); NvOsDebugPrintf("DTT: Invalid Range = %d\n", Range); pDtt->TcorePolicy.HighLimit = ODM_TMON_PARAMETER_UNSPECIFIED; pDtt->TcorePolicy.LowLimit = ODM_TMON_PARAMETER_UNSPECIFIED; pDtt->TcorePolicy.PolicyRange = NvRmDttAp20PolicyRange_Unknown; return; } pDtt->TcorePolicy.PolicyRange = (NvU32)Range; }
float nv_shapecontext_distance(const nv_shapecontext_t *sctx1, const nv_shapecontext_t *sctx2) { float distance = 0.0f; int points = NV_MIN(sctx1->n, sctx2->n); int m, n; nv_matrix_t *cost_matrix = nv_matrix_alloc(points, points); nv_matrix_t *mincost = nv_matrix_alloc(points, 1); #ifdef _DEBUG FILE *f1 = fopen("1.dat", "w"); FILE *f2 = fopen("2.dat", "w"); FILE *fd = fopen("d.dat", "w"); if (sctx1->n != points) { const nv_shapecontext_t *t1 = sctx1; sctx1 = sctx2; sctx2 = t1; } #endif // cosine distance nv_matrix_zero(cost_matrix); for (m = 0; m < points; ++m) { for (n = 0; n < points; ++n) { float cosdist = x2_test(sctx1->sctx, m, sctx2->sctx, n);//cos_distance(sctx1->sctx, m, sctx2->sctx, n); float dy = NV_MAT_V(sctx1->coodinate, m, 0) - NV_MAT_V(sctx2->coodinate, n, 0); float dx = NV_MAT_V(sctx1->coodinate, m, 1) - NV_MAT_V(sctx2->coodinate, n, 1); float rx2 = (NV_MAT_V(sctx1->radius, m, 0) + NV_MAT_V(sctx2->radius, n, 0)); float eudist = sqrtf(dy * dy + dx * dx)/sqrtf(rx2*rx2); float v = 1.0f * eudist + 0.9f * cosdist; NV_MAT_V(cost_matrix, m, n) = v; } } distance += nv_munkres(mincost, cost_matrix) / points; #ifdef _DEBUG for (m = 0; m < sctx1->n; ++m) { fprintf(f1, "%f %f\n", NV_MAT_V(sctx1->coodinate, m, 1), NV_MAT_V(sctx1->coodinate, m, 0)); } for (n = 0; n < sctx2->n; ++n) { fprintf(f2, "%f %f\n", NV_MAT_V(sctx2->coodinate, n, 1), NV_MAT_V(sctx2->coodinate, n, 0)); } for (n = 0; n < sctx2->n;++n) { fprintf(fd, "%f %f\n", NV_MAT_V(sctx2->coodinate, n, 1), NV_MAT_V(sctx2->coodinate, n, 0)); fprintf(fd, "%f %f\n", NV_MAT_V(sctx1->coodinate, NV_MAT_VI(mincost, 0, n), 1), NV_MAT_V(sctx1->coodinate, NV_MAT_VI(mincost, 0, n), 0)); fprintf(fd, "\n\n"); } fclose(f1); fclose(f2); fclose(fd); #endif nv_matrix_free(&cost_matrix); nv_matrix_free(&mincost); return distance; }
void nv_shapecontext_feature(nv_shapecontext_t *sctx, const nv_matrix_t *img, float r ) { int m, row, col, pc, i, l; nv_matrix_t *edge = nv_matrix3d_alloc(1, img->rows, img->cols); nv_matrix_t *points = nv_matrix_alloc(2, img->m); int *rand_idx = (int *)nv_malloc(sizeof(int) * img->m); float u_x, u_y, p_x, p_y, r_e; int pn; // 細線化 nv_matrix_zero(points); nv_shapecontext_edge_image(edge, img); pc = 0; u_x = 0.0f; u_y = 0.0f; for (row = 0; row < edge->rows; ++row) { for (col = 0; col < edge->cols; ++col) { if (NV_MAT3D_V(edge, row, col, 0) > 50.0f) { NV_MAT_V(points, pc, 0) = (float)row; NV_MAT_V(points, pc, 1) = (float)col; ++pc; u_y += (float)row; u_x += (float)col; } } } u_x /= pc; u_y /= pc; // 指定数の特徴にする(ランダム) pn = NV_MIN(pc, sctx->sctx->list); nv_shuffle_index(rand_idx, 0, pc); #if 1 { float max_x, max_y; if (pc < sctx->sctx->list) { // 足りないときはランダムに増やす for (i = pc; i < sctx->sctx->list; ++i) { rand_idx[i] = (int)(nv_rand() * pn); } } pc = pn = sctx->sctx->list; // 半径を求める max_x = 0.0f; max_y = 0.0f; for (m = 0; m < pn; ++m) { float yd = fabsf(NV_MAT_V(points, rand_idx[m], 0) - u_y); float xd = fabsf(NV_MAT_V(points, rand_idx[m], 1) - u_x); max_x = NV_MAX(max_x, xd); max_y = NV_MAX(max_y, yd); } r = (float)img->rows/2.0f;//NV_MAX(max_x, max_y) * 1.0f; } #endif // log(r) = 5の基底定数を求める r_e = powf(r, 1.0f / NV_SC_LOG_R_BIN); // histgramを計算する sctx->n = pn; nv_matrix_zero(sctx->sctx); nv_matrix_zero(sctx->tan_angle); for (l = 0; l < pn; ++l) { // tangent angle #if 0 float max_bin = 0.0f, min_bin = FLT_MAX; float tan_angle = tangent_angle( r, NV_MAT_V(points, rand_idx[l], 0), NV_MAT_V(points, rand_idx[l], 1), points, pc); #else float tan_angle = 0.0f; #endif p_y = NV_MAT_V(points, rand_idx[l], 0); p_x = NV_MAT_V(points, rand_idx[l], 1); NV_MAT_V(sctx->tan_angle, l, 0) = tan_angle; NV_MAT_V(sctx->coodinate, l, 0) = p_y; NV_MAT_V(sctx->coodinate, l, 1) = p_x; NV_MAT_V(sctx->radius, l, 0) = r; // shape context for (i = 0; i < pn; ++i) { // # i ≠ l判定はとりあえずしない float xd = NV_MAT_V(points, rand_idx[i], 1) - p_x; float yd = NV_MAT_V(points, rand_idx[i], 0) - p_y; //int row = i / img->rows; //int col = i % img->rows; //float xd = col - p_x; //float yd = row - p_y; float theta; float log_r = logf(sqrtf(xd * xd + yd * yd)) / logf(r_e); float atan_r = atan2f(xd, yd); //if (NV_MAT3D_V(img, row, col, 0) == 0.0f) { // continue; //} if (i == l) { continue; } if (atan_r < 0.0f) { atan_r = 2.0f * NV_PI + atan_r; } if (tan_angle > 0.0f) { if (atan_r + tan_angle > 2.0f * NV_PI) { atan_r = atan_r + tan_angle - 2.0f * NV_PI; } else { atan_r += tan_angle; } } else { if (atan_r + tan_angle < 0.0f) { atan_r = 2.0f * NV_PI + (atan_r + tan_angle); } else { atan_r += tan_angle; } } theta = atan_r / (2.0f * NV_PI / NV_SC_THETA_BIN); if (theta < NV_SC_THETA_BIN && log_r < NV_SC_LOG_R_BIN) { NV_MAT3D_LIST_V(sctx->sctx, l, (int)log_r, (int)theta, 0) += 1.0f; } } #if 0 for (row = 0; row < NV_SC_LOG_R_BIN; ++row) { for (col = 0; col < NV_SC_THETA_BIN; ++col) { max_bin = NV_MAX(max_bin, NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0)); min_bin = NV_MIN(min_bin, NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0)); } } if (max_bin > 0.0f) { for (row = 0; row < NV_SC_LOG_R_BIN; ++row) { for (col = 0; col < NV_SC_THETA_BIN; ++col) { NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0) = (NV_MAT3D_LIST_V(sctx->sctx, l, row, col, 0) - min_bin) / (max_bin - min_bin); } } } #endif } nv_matrix_free(&edge); nv_matrix_free(&points); nv_free(rand_idx); }