Finds vertical and horizontal line objects in the given pix and removes them.
Uses the given resolution to determine size thresholds instead of any that may be present in the pix.
The output vertical_x and vertical_y contain a sum of the output vectors, thereby giving the mean vertical direction.
If pix_music_mask != nullptr, and music is detected, a mask of the staves and anything that is connected (bars, notes etc.) will be returned in pix_music_mask, the mask subtracted from pix, and the lines will not appear in v_lines or h_lines.
The output vectors are owned by the list and Frozen (cannot refit) by having no boxes, as there is no need to refit or merge separator lines.
The detected lines are removed from the pix.
693 {
694 if (pix == nullptr || vertical_x == nullptr || vertical_y == nullptr) {
695 tprintf(
"Error in parameters for LineFinder::FindAndRemoveLines\n");
696 return;
697 }
698 Image pix_vline = nullptr;
699 Image pix_non_vline = nullptr;
700 Image pix_hline = nullptr;
701 Image pix_non_hline = nullptr;
702 Image pix_intersections = nullptr;
703 Pixa *pixa_display = debug ? pixaCreate(0) : nullptr;
704 GetLineMasks(resolution, pix, &pix_vline, &pix_non_vline, &pix_hline, &pix_non_hline,
705 &pix_intersections, pix_music_mask, pixa_display);
706
707 FindAndRemoveVLines(pix_intersections, vertical_x, vertical_y, &pix_vline,
708 pix_non_vline, pix, v_lines);
709 pix_intersections.destroy();
710 if (pix_hline != nullptr) {
711
712 if (pix_vline != nullptr) {
713 pix_intersections = pix_vline & pix_hline;
714 }
715 if (!FilterFalsePositives(resolution, pix_non_hline, pix_intersections, pix_hline)) {
716 pix_hline.destroy();
717 }
718 }
719 FindAndRemoveHLines(pix_intersections, *vertical_x, *vertical_y, &pix_hline,
720 pix_non_hline, pix, h_lines);
721 if (pixa_display != nullptr && pix_vline != nullptr) {
722 pixaAddPix(pixa_display, pix_vline, L_CLONE);
723 }
724 if (pixa_display != nullptr && pix_hline != nullptr) {
725 pixaAddPix(pixa_display, pix_hline, L_CLONE);
726 }
727 pix_intersections.destroy();
728 if (pix_vline != nullptr && pix_hline != nullptr) {
729
730
731 pix_intersections = pix_vline & pix_hline;
732
733
734 Image pix_join_residue = pixDilateBrick(nullptr, pix_intersections, 5, 5);
735 pixSeedfillBinary(pix_join_residue, pix_join_residue, pix, 8);
736
737 pixSubtract(pix, pix, pix_join_residue);
738 pix_join_residue.destroy();
739 }
740
741 if (pix_music_mask != nullptr && *pix_music_mask != nullptr) {
742 if (pixa_display != nullptr) {
743 pixaAddPix(pixa_display, *pix_music_mask, L_CLONE);
744 }
745 pixSubtract(pix, pix, *pix_music_mask);
746 }
747 if (pixa_display != nullptr) {
748 pixaAddPix(pixa_display, pix, L_CLONE);
749 }
750
751 pix_vline.destroy();
752 pix_non_vline.destroy();
753 pix_hline.destroy();
754 pix_non_hline.destroy();
755 pix_intersections.destroy();
756 if (pixa_display != nullptr) {
757 pixaConvertToPdf(pixa_display, resolution, 1.0f, 0, 0, "LineFinding", "vhlinefinding.pdf");
758 pixaDestroy(&pixa_display);
759 }
760}
void tprintf(const char *format,...)