std::vector<cv::Scalar> readLabelColors(const cv::Mat3b img, const std::vector<cv::Point2f>& points) { std::vector<cv::Scalar> label_colors; cv::Rect img_rect(cv::Point(0,0), img.size()); for (const auto& p :points) { if (img_rect.contains(p)) { label_colors.push_back(img(p)); } } if (label_colors.size() == 9*3) { return label_colors; } else { return {}; } }
static void GenSmallImage( int img_count, CImage &back, const RectF &render_rect, int sel, CImage &img_alpha ) { #define RAND_ALPHA ( ( 130 + random( 50 ) ) / 255.0f ) #define ROT_ANGLE ( random( 20 ) + 160 ) if( img_count < 1 ) { return ; } CFileListManager &file_manager = GetInst( CFileListManager ); const Range &alpha_r = GetInst( CConfiger ).GetSystem().AnswerAlphaRange; float fAnswerAlpha = ( random( alpha_r.second - alpha_r.first ) + alpha_r.first ) / 255.0f; CImage img_first; CreateImgFromBuffer( file_manager.GetRandSmall(), img_first, true ); float fFirstRot = ROT_ANGLE; float fFirstAlpha = RAND_ALPHA; PointF pos = RotateImage( img_first, img_alpha, img_count == 1 ? ( random( 60 ) - 30.0f ) : fFirstRot ); PointF render_pos = GetRandPosInULRect( img_first.GetWidth(), img_first.GetHeight(), render_rect ); RectF img_rect( render_pos.X + 20, render_pos.Y + 20, img_first.GetWidth() - 40, img_first.GetHeight() - 40 ); back.AlphaBlend( &img_first, render_pos.X, render_pos.Y, img_count == 1 ? fAnswerAlpha : fFirstAlpha ); CImage *img_cover = NULL; PointF rot_pos = GetRotPos( img_alpha, pos ); float fRotQuo = 20.0f; float fAlphaQuo = -0.08f; for( int i = 1; i < img_count; ++ i, fRotQuo += fRotQuo, fAlphaQuo += fAlphaQuo ) { img_cover = MP_NEW CImage(); CreateImgFromBuffer( file_manager.GetRandSmall(), *img_cover, true ); img_cover->RotateEx( fFirstRot + fRotQuo, rot_pos.X, rot_pos.Y ); img_cover->SetAlphaMap( &img_alpha, pos.X, pos.Y ); back.AlphaBlend( img_cover, render_pos.X, render_pos.Y, fFirstAlpha + fAlphaQuo ); MP_DELETE(img_cover); } BlendSelSign( back, img_rect, sel ); }
/** generate some small images and render them on the backgroun. */ static void GenSmallImage( int img_count, Gdiplus::Graphics *g, const Gdiplus::RectF &render_rect, int sel ) { #define RAND_ALPHA ( 100 + random( 55 ) ) if( img_count < 1 ) { return; } CFileListManager &file_manager = GetInst( CFileListManager ); // render without alpha value Gdiplus::Image *img = CreateImgFromBuffer( file_manager.GetRandSmall() ); Gdiplus::PointF render_pos = GetRandPosInULRect( img->GetWidth(), img->GetHeight(), render_rect ); Gdiplus::RectF img_rect( render_pos.X, render_pos.Y, (float)img->GetWidth(), (float)img->GetHeight() ); img_alpha( g, img, render_pos.X, render_pos.Y, img_count == 1 ? 255 : RAND_ALPHA ); delete img; // render with random alpha value and random rotation degree g->SetClip( img_rect ); for( int i = 1; i < img_count; ++ i ) { img = CreateImgFromBuffer( file_manager.GetRandSmall() ); img_rotate( g, img, render_pos.X, render_pos.Y, img->GetWidth() / 2, img->GetHeight() / 2, random( 360 ), // [0-360) RAND_ALPHA ); // [100-155) delete img; } g->ResetClip(); // blend a 'X' sign onto the picture if it's not the answer if( img_count > 1 ) { //BlendXSign( g, img_rect ); } // blend 'A''B''C''D' sign. BlendSelSign( g, img_rect, sel ); }
void SubtitleScreen::DisplayAVSubtitles(void) { if (!m_player || !m_subreader) return; AVSubtitles* subs = m_subreader->GetAVSubtitles(); QMutexLocker lock(&(subs->lock)); if (subs->buffers.empty() && (kDisplayAVSubtitle != m_subtitleType)) return; VideoOutput *videoOut = m_player->GetVideoOutput(); VideoFrame *currentFrame = videoOut ? videoOut->GetLastShownFrame() : NULL; if (!currentFrame || !videoOut) return; float tmp = 0.0; QRect dummy; videoOut->GetOSDBounds(dummy, m_safeArea, tmp, tmp, tmp); while (!subs->buffers.empty()) { const AVSubtitle subtitle = subs->buffers.front(); if (subtitle.start_display_time > currentFrame->timecode) break; ClearDisplayedSubtitles(); subs->buffers.pop_front(); for (std::size_t i = 0; i < subtitle.num_rects; ++i) { AVSubtitleRect* rect = subtitle.rects[i]; bool displaysub = true; if (subs->buffers.size() > 0 && subs->buffers.front().end_display_time < currentFrame->timecode) { displaysub = false; } if (displaysub && rect->type == SUBTITLE_BITMAP) { // AVSubtitleRect's image data's not guaranteed to be 4 byte // aligned. QSize img_size(rect->w, rect->h); QRect img_rect(rect->x, rect->y, rect->w, rect->h); QRect display(rect->display_x, rect->display_y, rect->display_w, rect->display_h); // XSUB and some DVD/DVB subs are based on the original video // size before the video was converted. We need to guess the // original size and allow for the difference int right = rect->x + rect->w; int bottom = rect->y + rect->h; if (subs->fixPosition || (currentFrame->height < bottom) || (currentFrame->width < right)) { int sd_height = 576; if ((m_player->GetFrameRate() > 26.0f) && bottom <= 480) sd_height = 480; int height = ((currentFrame->height <= sd_height) && (bottom <= sd_height)) ? sd_height : ((currentFrame->height <= 720) && bottom <= 720) ? 720 : 1080; int width = ((currentFrame->width <= 720) && (right <= 720)) ? 720 : ((currentFrame->width <= 1280) && (right <= 1280)) ? 1280 : 1920; display = QRect(0, 0, width, height); } QRect scaled = videoOut->GetImageRect(img_rect, &display); QImage qImage(img_size, QImage::Format_ARGB32); for (int y = 0; y < rect->h; ++y) { for (int x = 0; x < rect->w; ++x) { const uint8_t color = rect->pict.data[0][y*rect->pict.linesize[0] + x]; const uint32_t pixel = *((uint32_t*)rect->pict.data[1]+color); qImage.setPixel(x, y, pixel); } } if (scaled.size() != img_size) { qImage = qImage.scaled(scaled.width(), scaled.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } MythPainter *osd_painter = videoOut->GetOSDPainter(); MythImage* image = NULL; if (osd_painter) image = osd_painter->GetFormatImage(); long long displayfor = subtitle.end_display_time - subtitle.start_display_time; if (displayfor == 0) displayfor = 60000; displayfor = (displayfor < 50) ? 50 : displayfor; long long late = currentFrame->timecode - subtitle.start_display_time; MythUIImage *uiimage = NULL; if (image) { image->Assign(qImage); QString name = QString("avsub%1").arg(i); uiimage = new MythUIImage(this, name); if (uiimage) { m_refreshArea = true; uiimage->SetImage(image); uiimage->SetArea(MythRect(scaled)); m_expireTimes.insert(uiimage, currentFrame->timecode + displayfor); } } if (uiimage) { LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Display %1AV subtitle for %2ms") .arg(subtitle.forced ? "FORCED " : "") .arg(displayfor)); if (late > 50) LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("AV Sub was %1ms late").arg(late)); } } #ifdef USING_LIBASS else if (displaysub && rect->type == SUBTITLE_ASS) { InitialiseAssTrack(m_player->GetDecoder()->GetTrack(kTrackTypeSubtitle)); AddAssEvent(rect->ass); } #endif } m_subreader->FreeAVSubtitle(subtitle); } #ifdef USING_LIBASS RenderAssTrack(currentFrame->timecode); #endif }
void Mapper::drawMinimap() { video::ITexture *minimap_texture = getMinimapTexture(); if (!minimap_texture) return; updateActiveMarkers(); v2u32 screensize = porting::getWindowSize(); const u32 size = 0.25 * screensize.Y; core::rect<s32> oldViewPort = driver->getViewPort(); core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); driver->setViewPort(core::rect<s32>( screensize.X - size - 10, 10, screensize.X - 10, size + 10)); driver->setTransform(video::ETS_PROJECTION, core::matrix4()); driver->setTransform(video::ETS_VIEW, core::matrix4()); core::matrix4 matrix; matrix.makeIdentity(); video::SMaterial &material = m_meshbuffer->getMaterial(); material.setFlag(video::EMF_TRILINEAR_FILTER, true); material.Lighting = false; material.TextureLayer[0].Texture = minimap_texture; material.TextureLayer[1].Texture = data->heightmap_texture; if (m_enable_shaders && !data->is_radar) { u16 sid = m_shdrsrc->getShader("minimap_shader", 1, 1); material.MaterialType = m_shdrsrc->getShaderInfo(sid).material; } else { material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; } if (data->minimap_shape_round) matrix.setRotationDegrees(core::vector3df(0, 0, 360 - m_angle)); // Draw minimap driver->setTransform(video::ETS_WORLD, matrix); driver->setMaterial(material); driver->drawMeshBuffer(m_meshbuffer); // Draw overlay video::ITexture *minimap_overlay = data->minimap_shape_round ? data->minimap_overlay_round : data->minimap_overlay_square; material.TextureLayer[0].Texture = minimap_overlay; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; driver->setMaterial(material); driver->drawMeshBuffer(m_meshbuffer); // If round minimap, draw player marker if (!data->minimap_shape_round) { matrix.setRotationDegrees(core::vector3df(0, 0, m_angle)); material.TextureLayer[0].Texture = data->player_marker; driver->setTransform(video::ETS_WORLD, matrix); driver->setMaterial(material); driver->drawMeshBuffer(m_meshbuffer); } // Reset transformations driver->setTransform(video::ETS_VIEW, oldViewMat); driver->setTransform(video::ETS_PROJECTION, oldProjMat); driver->setViewPort(oldViewPort); // Draw player markers v2s32 s_pos(screensize.X - size - 10, 10); core::dimension2di imgsize(data->object_marker_red->getOriginalSize()); core::rect<s32> img_rect(0, 0, imgsize.Width, imgsize.Height); static const video::SColor col(255, 255, 255, 255); static const video::SColor c[4] = {col, col, col, col}; f32 sin_angle = sin(m_angle * core::DEGTORAD); f32 cos_angle = cos(m_angle * core::DEGTORAD); s32 marker_size2 = 0.025 * (float)size; for (std::list<v2f>::const_iterator i = m_active_markers.begin(); i != m_active_markers.end(); ++i) { v2f posf = *i; if (data->minimap_shape_round) { f32 t1 = posf.X * cos_angle - posf.Y * sin_angle; f32 t2 = posf.X * sin_angle + posf.Y * cos_angle; posf.X = t1; posf.Y = t2; } posf.X = (posf.X + 0.5) * (float)size; posf.Y = (posf.Y + 0.5) * (float)size; core::rect<s32> dest_rect( s_pos.X + posf.X - marker_size2, s_pos.Y + posf.Y - marker_size2, s_pos.X + posf.X + marker_size2, s_pos.Y + posf.Y + marker_size2); driver->draw2DImage(data->object_marker_red, dest_rect, img_rect, &dest_rect, &c[0], true); } }
void set(cv::Mat src_mat, std::vector<bbox_t> result_vec) { size_t const count_preview_boxes = src_mat.cols / preview_box_size; if (preview_box_track_id.size() != count_preview_boxes) preview_box_track_id.resize(count_preview_boxes); // increment frames history for (auto &i : preview_box_track_id) i.last_showed_frames_ago = std::min((unsigned)frames_history, i.last_showed_frames_ago + 1); // occupy empty boxes for (auto &k : result_vec) { bool found = false; // find the same (track_id) for (auto &i : preview_box_track_id) { if (i.track_id == k.track_id) { if (!one_off_detections) i.last_showed_frames_ago = 0; // for tracked objects found = true; break; } } if (!found) { // find empty box for (auto &i : preview_box_track_id) { if (i.last_showed_frames_ago == frames_history) { if (!one_off_detections && k.frames_counter == 0) break; // don't show if obj isn't tracked yet i.track_id = k.track_id; i.obj_id = k.obj_id; i.bbox = k; i.last_showed_frames_ago = 0; break; } } } } // draw preview box (from old or current frame) for (size_t i = 0; i < preview_box_track_id.size(); ++i) { // get object image cv::Mat dst = preview_box_track_id[i].mat_resized_obj; preview_box_track_id[i].current_detection = false; for (auto &k : result_vec) { if (preview_box_track_id[i].track_id == k.track_id) { if (one_off_detections && preview_box_track_id[i].last_showed_frames_ago > 0) { preview_box_track_id[i].last_showed_frames_ago = frames_history; break; } bbox_t b = k; cv::Rect r(b.x, b.y, b.w, b.h); cv::Rect img_rect(cv::Point2i(0, 0), src_mat.size()); cv::Rect rect_roi = r & img_rect; if (rect_roi.width > 1 || rect_roi.height > 1) { cv::Mat roi = src_mat(rect_roi); cv::resize(roi, dst, cv::Size(preview_box_size, preview_box_size), cv::INTER_NEAREST); preview_box_track_id[i].mat_obj = roi.clone(); preview_box_track_id[i].mat_resized_obj = dst.clone(); preview_box_track_id[i].current_detection = true; preview_box_track_id[i].bbox = k; } break; } } } }