//======================================================================= //function : Perform //purpose : //======================================================================= void GEOMAlgo_GlueDetector::Perform() { myErrorStatus=0; myWarningStatus=0; // CheckData(); if (myErrorStatus) { return; } // DetectVertices(); if (myErrorStatus) { return; } // DetectEdges(); if (myErrorStatus) { return; } // DetectFaces(); if (myErrorStatus) { return; } }
void QuadricCollision::DetectCollision(WF_edge *target_e, vector<WF_edge*> exist_edge, vector<GeoV3> &output) { output.clear(); double ¦È, ¦Õ; target_e_ = target_e; //North Point if (!DetectEdges(exist_edge, 0, 0)) output.push_back(Orientation(0, 0)); for (int j = 0; j < 3; j++) { for (int i = 0; i < divide_; i++) { if (i < 20) { ¦È = (j * 3 + 1)*18.0 / 180.0*F_PI; ¦Õ = i*18.0 / 180.0*F_PI; } if (i>19 && i < 40) { ¦È = (j * 3 + 2) * 18.0 / 180.0*F_PI; ¦Õ = (i - 20)*18.0 / 180.0*F_PI; } if (i>39) { ¦È = (j * 3 + 3)* 18.0 / 180.0*F_PI; ¦Õ = (i - 40)*18.0 / 180.0*F_PI; }
//======================================================================= //function : Perform //purpose : //======================================================================= void GEOMAlgo_GlueAnalyser::Perform() { myErrorStatus=0; myWarningStatus=0; // mySolidsToGlue.Clear(); mySolidsAlone.Clear(); // CheckData(); if (myErrorStatus) { return; } // // Initialize the context GEOMAlgo_ShapeAlgo::Perform(); // InnerTolerance(); if (myErrorStatus) { return; } // DetectVertices(); if (myErrorStatus) { return; } // DetectEdges(); if (myErrorStatus) { return; } // DetectFaces(); if (myErrorStatus) { return; } // DetectSolids(); if (myErrorStatus) { return; } }
void CannyFilter::PerformSteps(Ptr<Texture> output) { ReserveColorBuffers(2); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); GraphicsDevice::SetBuffers(PerPixelVertices, nullptr); histogram->Use(); histogram->Uniforms["Texture"].SetValue(*Input); RenderToTexture(ColorBuffers[1], PrimitiveType::Points, GL_COLOR_BUFFER_BIT); glDisable(GL_BLEND); GraphicsDevice::UseDefaultBuffers(); // todo: maybe the histogram generation can be done in the gray filter. Slower because of the per pixel vertices, but probably faster than a whole extra pass auto pixels = FrameBuffer::GetCurrentlyBound()->ReadPixels<float>(0, 0, 255, 1, GL_RED, GL_FLOAT); // Estimate median from frequencies float count = Input->GetWidth() * Input->GetHeight(); float percentile = 0; int i; for(i = 0; i < 255 && percentile < 0.5; ++i) percentile += pixels[i] / count; float median = i / 255.0f; gaussian->Input = Input; ApplyFilter(*gaussian, ColorBuffers[0]); ScharrAveraging(*ColorBuffers[0], output); Differentiation(*output, ColorBuffers[0]); //glEnable(GL_STENCIL_TEST); // todo: why / 2 ? Would it benefit from contrast stretch? Or should I use the 0.33rd and 0.66th percentile?? That would actually make a lot more sense... DetectEdges(*ColorBuffers[0], 0.33f * median, 0.66f * median, output); // Buffer0 contains gradients DEBUG_FB("Edges"); //glDisable(GL_STENCIL_TEST); }
bool ClassicLogoDetector::searchForLogo(MythPlayer* player) { int seekIncrement = (int)(commDetectLogoSampleSpacing * player->GetFrameRate()); int maxLoops = commDetectLogoSamplesNeeded; EdgeMaskEntry *edgeCounts; unsigned int pos, i, x, y, dx, dy; int edgeDiffs[] = {5, 7, 10, 15, 20, 30, 40, 50, 60, 0 }; LOG(VB_COMMFLAG, LOG_INFO, "Searching for Station Logo"); logoInfoAvailable = false; edgeCounts = new EdgeMaskEntry[width * height]; // Back in 2005, a threshold of 50 minimum pixelsInMask was established. // I don't know whether that was tested against SD or HD resolutions. // I do know that in 2010, mythcommflag was changed to use ffmpeg's // lowres support, effectively dividing the video area by 16. // But the 50 pixel minimum was not adjusted accordingly. // I believe the minimum threshold should vary with the video's area. // I am using 1280x720 (for 720p) video as the baseline. // This should improve logo detection for SD video. int minPixelsInMask = 50 * (width*height) / (1280*720 / 16); for (i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++) { int pixelsInMask = 0; LOG(VB_COMMFLAG, LOG_INFO, QString("Trying with edgeDiff == %1, minPixelsInMask=%2") .arg(edgeDiffs[i]).arg(minPixelsInMask)); memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * width * height); memset(edgeMask, 0, sizeof(EdgeMaskEntry) * width * height); player->DiscardVideoFrame(player->GetRawVideoFrame(0)); int loops = 0; long long seekFrame = commDetector->preRoll + seekIncrement; while (loops < maxLoops && player->GetEof() == kEofStateNone) { VideoFrame* vf = player->GetRawVideoFrame(seekFrame); if ((loops % 50) == 0) commDetector->logoDetectorBreathe(); if (commDetector->m_bStop) { player->DiscardVideoFrame(vf); delete[] edgeCounts; return false; } if (!commDetector->fullSpeed) std::this_thread::sleep_for(std::chrono::milliseconds(10)); DetectEdges(vf, edgeCounts, edgeDiffs[i]); seekFrame += seekIncrement; loops++; player->DiscardVideoFrame(vf); } LOG(VB_COMMFLAG, LOG_INFO, "Analyzing edge data"); #ifdef SHOW_DEBUG_WIN unsigned char *fakeFrame; fakeFrame = new unsigned char[width * height * 3 / 2]; memset(fakeFrame, 0, width * height * 3 / 2); #endif for (y = 0; y < height; y++) { if ((y > (height/4)) && (y < (height * 3 / 4))) continue; for (x = 0; x < width; x++) { if ((x > (width/4)) && (x < (width * 3 / 4))) continue; pos = y * width + x; if (edgeCounts[pos].isedge > (maxLoops * 0.66)) { edgeMask[pos].isedge = 1; pixelsInMask++; #ifdef SHOW_DEBUG_WIN fakeFrame[pos] = 0xff; #endif } if (edgeCounts[pos].horiz > (maxLoops * 0.66)) edgeMask[pos].horiz = 1; if (edgeCounts[pos].vert > (maxLoops * 0.66)) edgeMask[pos].vert = 1; if (edgeCounts[pos].ldiag > (maxLoops * 0.66)) edgeMask[pos].ldiag = 1; if (edgeCounts[pos].rdiag > (maxLoops * 0.66)) edgeMask[pos].rdiag = 1; } } SetLogoMaskArea(); for (y = logoMinY; y < logoMaxY; y++) { for (x = logoMinX; x < logoMaxX; x++) { int neighbors = 0; if (!edgeMask[y * width + x].isedge) continue; for (dy = y - 2; dy <= (y + 2); dy++ ) { for (dx = x - 2; dx <= (x + 2); dx++ ) { if (edgeMask[dy * width + dx].isedge) neighbors++; } } if (neighbors < 5) edgeMask[y * width + x].isedge = 0; } } SetLogoMaskArea(); LOG(VB_COMMFLAG, LOG_INFO, QString("Testing Logo area: topleft (%1,%2), bottomright (%3,%4)") .arg(logoMinX).arg(logoMinY) .arg(logoMaxX).arg(logoMaxY)); #ifdef SHOW_DEBUG_WIN for (x = logoMinX; x < logoMaxX; x++) { pos = logoMinY * width + x; fakeFrame[pos] = 0x7f; pos = logoMaxY * width + x; fakeFrame[pos] = 0x7f; } for (y = logoMinY; y < logoMaxY; y++) { pos = y * width + logoMinX; fakeFrame[pos] = 0x7f; pos = y * width + logoMaxX; fakeFrame[pos] = 0x7f; } comm_debug_show(fakeFrame); delete [] fakeFrame; cerr << "Hit ENTER to continue" << endl; getchar(); #endif if (((logoMaxX - logoMinX) < (width / 4)) && ((logoMaxY - logoMinY) < (height / 4)) && (pixelsInMask > minPixelsInMask)) { logoInfoAvailable = true; logoEdgeDiff = edgeDiffs[i]; LOG(VB_COMMFLAG, LOG_INFO, QString("Using Logo area: topleft (%1,%2), " "bottomright (%3,%4), pixelsInMask (%5).") .arg(logoMinX).arg(logoMinY) .arg(logoMaxX).arg(logoMaxY) .arg(pixelsInMask)); } else { LOG(VB_COMMFLAG, LOG_INFO, QString("Rejecting Logo area: topleft (%1,%2), " "bottomright (%3,%4), pixelsInMask (%5). " "Not within specified limits.") .arg(logoMinX).arg(logoMinY) .arg(logoMaxX).arg(logoMaxY) .arg(pixelsInMask)); } } delete [] edgeCounts; if (!logoInfoAvailable) LOG(VB_COMMFLAG, LOG_NOTICE, "No suitable logo area found."); player->DiscardVideoFrame(player->GetRawVideoFrame(0)); return logoInfoAvailable; }