Ask Your Question
1

Filling a dynamic model

asked 2015-09-18 02:37:53 -0500

sarjoondeen gravatar image

updated 2015-09-18 09:21:01 -0500

Hi all,

I am working a project where I have to create a dynamic model for the received input image. This is the input image kiwi_defect.jpeg

I have create a dynamic model using Convex Hull This is the model [ContourImageModel.jpg]

ContourImageModel.jpg

I want to fill the model with respective to of the original image Thing is I need to compare the convexhull model with original image and need to fill the pixels except that the black area in the the original image need to be filled with the surrounding white pixels. Like this image [model.jpeg] [model.jpeg](/upfiles/14425619881537103.jpeg)

And I have a problem in filling it in that manner. Please help me in this. Is this any function is there in opencv which will help me to compare the neighbouring pixels and fill the current pixel.. ?

I know that this requires some analytical thinking and knowledge which I am lagging at. And I know there is median filter, flood fill functions which I think its not a proper way to fill.

So please guide me in this.

  1. kiwi_defect.jpeg

  2. ContourImageModel.jpg

  3. model.jpeg

Thanks in Advance

Regards, Sarjoon.

edit retag flag offensive close merge delete

Comments

Original image is kiwi_defect.jpeg. After you look for convex Hull. (I'm not that your contour is convex near point(335,190)).

After I don't understand what do you want?

If you want to fill your shape with original pixel value you can add ContourImageModel.jpg and kiwi_defect.jpeg. Some pixel will stay black.Your problem is for those pixels?

LBerger gravatar imageLBerger ( 2015-09-18 09:49:44 -0500 )edit

Yes you got the point. If i merge, those black pixels will also will come.

I dont want that. Those black pixels are the defects on the kiwi fruit layer which I want to remove from the model. I want to fill those defect pixels with the surrounding non-defect pixels, so that it will create a ideal model with only non-defect pixels (Refer model.jpeg, some thing like that I need)

sarjoondeen gravatar imagesarjoondeen ( 2015-09-18 09:54:16 -0500 )edit

fill outside of your shape with 255.

Add this new image with your shape

for black pixel look for nearest neihbour in original image and set pixel value to meanvalue found.

LBerger gravatar imageLBerger ( 2015-09-18 10:03:40 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2015-09-19 05:40:09 -0500

LBerger gravatar image

I have add some lines to this program

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <map>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

Mat src; Mat src_gray;
map <int ,vector<Point > > arrayNeighbour;
int thresh = 100,valRef=255;
int max_thresh = 255;
RNG rng(12345);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
vector<vector<Point> >hull( contours.size() );
Mat imThresh;

/** @function thresh_callback */
void thresh_callback(int, void* )
{
Mat src_copy = src.clone();
Mat threshold_output;
/// Detect edges using Threshold
threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
imThresh =threshold_output.clone();
/// Find contours
findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

/// Find the convex hull object for each contour
    hull.resize( contours.size() );
for( int i = 0; i < contours.size(); i++ )
    {  convexHull( Mat(contours[i]), hull[i], false ); }

/// Draw contours + hull results
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
    {
    Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
    drawContours( drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
    }

/// Show in a window
namedWindow( "Hull demo", CV_WINDOW_AUTOSIZE );
imshow( "Hull demo", drawing );

}
void InitMapDist(Mat src)
{
    for (int i=-src.rows/2;i<src.rows/2;i++)
        for (int j = -src.cols / 2; j < src.cols / 2; j++)
        {
            if (arrayNeighbour.find(i*i + j*j) == arrayNeighbour.end())
            {
                vector<Point> v;
                arrayNeighbour.insert(make_pair(i*i+j*j,v));
            }
            arrayNeighbour[i*i + j*j].push_back(Point(i,j));
        }

}


int LookForNearest(Mat imgThresh, Mat src, int l, int c, int nb)
{
    int nbFound=0;
    vector<int> pixel;
    int dist=1;
    map<int,vector<Point> >::iterator it=arrayNeighbour.begin();
    float mean=0;
    while (nbFound < nb && it!=arrayNeighbour.end())
    {
        for (int i = 0; i < it->second.size(); i++)
        {
            Point p=Point(l,c)+it->second[i];
            if (p.x >= 0 && p.x < imgThresh.cols && p.y >= 0 && p.y < imgThresh.rows)
            {
                if (imgThresh.at<uchar>(p.y, p.x) == valRef)
                {
                    nbFound++;
                    mean+=src.at<uchar>(p.y, p.x);
                }

            }

        }
        it++;
    }
return mean/nbFound;
}

int main( int argc, char** argv )
{
/// Load source image and convert it to gray
src_gray = imread( "c:/Users/Laurent.PC-LAURENT-VISI/Downloads/14425608212127298.jpeg", CV_LOAD_IMAGE_GRAYSCALE );

blur( src_gray, src_gray, Size(3,3) );
InitMapDist(src_gray);
waitKey();
/// Create Window
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src_gray );

createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey();

Mat img=255*Mat::ones(src_gray.size(),CV_8UC1);
Mat res=Mat::zeros(src_gray.size(),CV_8UC1);

double areaMax=0;
int iMax=0;
for (int i = 1; i<contours.size();i++)
{
    double area=contourArea(contours[i],false );
    if (area>areaMax)
    {
        iMax=i;
        areaMax=area;
    }
}
drawContours(img,hull, iMax,0,CV_FILLED);
imshow("HuLL",img);
imshow("imThresh",imThresh);

for (int i = 0; i<img.rows; i++)
{
    for (int j=0;j<img.cols;j++)
        if (img.at<uchar>(i,j)==0)
            if (imThresh.at<uchar>(i,j)==valRef)
                res.at<uchar>(i, j) = src_gray.at<uchar>(i,j);
            else
                res.at<uchar>(i ...
(more)
edit flag offensive delete link more

Comments

Thanks for the code . But the problem is whatever you are seeing their in the image is not the actually 255(white) and 0(black). There are different intensities in that range staring from 20 to 200 is there.

For that how we will get a reference value. how can we do that ?

sarjoondeen gravatar imagesarjoondeen ( 2015-09-30 05:16:43 -0500 )edit

I don't undestand. This program fill convexHull with a value equal to nearest neighbour mean. result is display in res like in this video.

LBerger gravatar imageLBerger ( 2015-09-30 07:11:01 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2015-09-18 02:37:53 -0500

Seen: 245 times

Last updated: Sep 19 '15