Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9266107
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T14:14:31+00:00 2026-06-18T14:14:31+00:00

I have retrieved all pixels from a png image which looks like this… I

  • 0

I have retrieved all pixels from a png image which looks like this…enter image description here

I started to get all filled lines horizontal to get the start end pixel of each line …. as I scan horizontal I get also the vertical lines in horizontal layer…. I guess it is possible to code all manually but it takes time…. my question is has anyone experience with opencv,imageJ or other to tell if any of this libs could solve the problem… I am also open for any algorithm suggestion…. (using Java)….

-> The biggest problem is the thickness of the lines between 1 and 4 pixels otherwise I could easily retrieve the joint points

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T14:14:32+00:00Added an answer on June 18, 2026 at 2:14 pm

    Here is a possible solution using image morphology. The code below is in C++ since I only have little experience with Java.

    To solve your problem, you need:

    • Thinning – to reduce thick lines to one-pixel width lines.
    • Hit-or-miss transform – for finding patterns in binary image i.e the corner and joint points.

    The bad news is both operations is not yet supported in OpenCV as of version 2.4.3. The good news is I have implemented both operations, the code is available on my blog:

    • void thinning(cv::Mat& im)
    • void hitmiss(cv::Mat& src, cv::Mat dst, cv::Mat& kernel)

    I will be using my thinning() and hitmiss() functions and your test image.

    After loading the image, convert it to single-channel binary image.

    cv::Mat im = cv::imread("D1Xnm.png");
    cv::Mat bw;
    cv::cvtColor(im, bw, CV_BGR2GRAY);
    cv::threshold(~bw, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
    

    enter image description here

    Since the width of the lines vary from 1 to 4 pixels perform thinning to get one-width lines.

    thinning(bw);
    

    enter image description here

    From the thinned image, notice that there are perfect and not perfect joint points as shown in the figure below.

    enter image description here
    enter image description here

    To cover both the perfect and imperfect joint points, we need the following kernels for the hit-or-miss transform.

    std::vector<cv::Mat> k;
    k.push_back((cv::Mat_<char>(5,5) << -1,-1, 0,-1,-1,
                                        -1,-1, 0,-1,-1,
                                         0, 0, 0, 0, 1,
                                        -1,-1, 0, 0,-1,
                                        -1,-1, 1,-1,-1 ));
    
    k.push_back((cv::Mat_<char>(5,5) << -1,-1, 0,-1,-1,
                                        -1,-1, 0,-1,-1,
                                         1, 0, 0, 0, 0,
                                        -1, 0, 0,-1,-1,
                                        -1,-1, 1,-1,-1 ));
    
    k.push_back((cv::Mat_<char>(5,5) << -1,-1, 1,-1,-1,
                                        -1,-1, 0,-1,-1,
                                         1, 0, 0, 0, 0,
                                        -1, 0, 0,-1,-1,
                                        -1,-1, 0,-1,-1 ));
    
    k.push_back((cv::Mat_<char>(5,5) << -1,-1, 1,-1,-1,
                                        -1,-1, 0,-1,-1,
                                         0, 0, 0, 0, 1,
                                        -1,-1, 0, 0,-1,
                                        -1,-1, 0,-1,-1 ));
    
    cv::Mat dst = cv::Mat::zeros(bw.size(), CV_8U);
    
    for (int i = 0; i < k.size(); i++)
    {
        cv::Mat tmp;
        hitmiss(bw, tmp, k[i]);
        dst |= tmp;
    }
    

    enter image description here

    Open the original image to make the result clearer.

    The joint points successfully located, draw it on the original image.

    std::vector<std::vector<cv::Point> > cnt;
    cv::findContours(dst.clone(), cnt, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    cv::drawContours(im, cnt, -1, CV_RGB(255,0,0), 10);
    

    enter image description here


    For the sake of completeness, here is the full code. With some efforts you can port it to Java.

    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    void thinningIteration(cv::Mat& im, int iter)
    {
        cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1);
    
        for (int i = 1; i < im.rows; i++)
        {
            for (int j = 1; j < im.cols; j++)
            {
                uchar p2 = im.at<uchar>(i-1, j);
                uchar p3 = im.at<uchar>(i-1, j+1);
                uchar p4 = im.at<uchar>(i, j+1);
                uchar p5 = im.at<uchar>(i+1, j+1);
                uchar p6 = im.at<uchar>(i+1, j);
                uchar p7 = im.at<uchar>(i+1, j-1);
                uchar p8 = im.at<uchar>(i, j-1);
                uchar p9 = im.at<uchar>(i-1, j-1);
    
                int A  = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) + 
                         (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) + 
                         (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) +
                         (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1);
                int B  = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
                int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8);
                int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8);
    
                if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
                    marker.at<uchar>(i,j) = 1;
            }
        }
        im &= ~marker;
    }
    
    void thinning(cv::Mat& im)
    {
        im /= 255;
        cv::Mat prev = cv::Mat::zeros(im.size(), CV_8UC1);
        cv::Mat diff;
        do {
            thinningIteration(im, 0);
            thinningIteration(im, 1);
            cv::absdiff(im, prev, diff);
            im.copyTo(prev);
        } 
        while (cv::countNonZero(diff) > 0);
        im *= 255;
    }
    
    void hitmiss(cv::Mat& src, cv::Mat& dst, cv::Mat& kernel) 
    {
        CV_Assert(src.type() == CV_8U && src.channels() == 1);
    
        cv::Mat k1 = (kernel == 1) / 255;
        cv::Mat k2 = (kernel == -1) / 255;
    
        cv::normalize(src, src, 0, 1, cv::NORM_MINMAX);
    
        cv::Mat e1, e2;
        cv::erode(src, e1, k1, cv::Point(-1,-1), 1, cv::BORDER_CONSTANT, cv::Scalar(0));
        cv::erode(1 - src, e2, k2, cv::Point(-1,-1), 1, cv::BORDER_CONSTANT, cv::Scalar(0));
        dst = e1 & e2;
    }
    
    int main()
    {
        cv::Mat im = cv::imread("D1Xnm.png");
        if (im.empty())
            return -1;
        cv::Mat bw;
        cv::cvtColor(im, bw, CV_BGR2GRAY);
        cv::threshold(~bw, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
        thinning(bw);
    
        std::vector<cv::Mat> k;
        k.push_back((cv::Mat_<char>(5,5) << -1,-1, 0,-1,-1,
                                            -1,-1, 0,-1,-1,
                                             0, 0, 0, 0, 1,
                                            -1,-1, 0, 0,-1,
                                            -1,-1, 1,-1,-1 ));
    
        k.push_back((cv::Mat_<char>(5,5) << -1,-1, 0,-1,-1,
                                            -1,-1, 0,-1,-1,
                                             1, 0, 0, 0, 0,
                                            -1, 0, 0,-1,-1,
                                            -1,-1, 1,-1,-1 ));
    
        k.push_back((cv::Mat_<char>(5,5) << -1,-1, 1,-1,-1,
                                            -1,-1, 0,-1,-1,
                                             1, 0, 0, 0, 0,
                                            -1, 0, 0,-1,-1,
                                            -1,-1, 0,-1,-1 ));
    
        k.push_back((cv::Mat_<char>(5,5) << -1,-1, 1,-1,-1,
                                            -1,-1, 0,-1,-1,
                                             0, 0, 0, 0, 1,
                                            -1,-1, 0, 0,-1,
                                            -1,-1, 0,-1,-1 ));
    
        cv::Mat dst = cv::Mat::zeros(bw.size(), CV_8U);
    
        for (int i = 0; i < k.size(); i++)
        {
            cv::Mat tmp;
            hitmiss(bw, tmp, k[i]);
            dst |= tmp;
        }
    
        std::vector<std::vector<cv::Point> > cnt;
        cv::findContours(dst.clone(), cnt, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
        cv::drawContours(im, cnt, -1, CV_RGB(255,0,0), 10);
    
        cv::imshow("src", im);
        cv::imshow("bw", bw*255);
        cv::imshow("dst", dst*255);
        cv::waitKey();
        return 0;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

i have this code, which helps me to retrieve all table fields and associate
I have never saved and retrieved an image to and from the database before.
I have retrieved data from a 2-column CSV file using HashMap. This is for
I have a problem with getting the pixels from an image. I load a
I have a layout that contains several sub-views all which set height like: <View
I have retrieved the all the imaged from sd card and displayed in my
I'm trying to serialize objects from a database that have been retrieved with Hibernate,
I have retrieved the name of the very first image saved in the media
I have a large collection of custom objects that I have retrieved from a
I have to handle large amount of data retrieved from server using ajax and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.