//=======================================================================
//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;
  }
}
示例#2
0
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;
  }
}
示例#4
0
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;
}