|   | 1 |  initial version  | 
i've answered a smilar question before.
i trial code based on convexityDefects gives you some key points.maybe you will improve it.
result images :
 
 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );
    if (src.empty())
        return -1;
    Mat bw;
    cvtColor( src, bw, COLOR_BGR2GRAY );
    bw = bw < 60;
    // Find contours
    vector<vector<Point> > contours;
    vector<int> contoursHull;
    vector<Vec4i> defects;
    findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    for ( size_t i = 0; i < contours.size(); i++)
    {
        if( contourArea(contours[i]) > 500 )
        {
            approxPolyDP(contours[i],contours[i],9,true);
            convexHull(contours[i], contoursHull,true);
            convexityDefects(contours[i], contoursHull,defects);
            for ( size_t j = 0; j <  defects.size(); j++)
            {
                Vec4i defpoint = defects[j];
                circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
            }
        }
    }
    imshow("result", src);
    waitKey();
    return 0;
}
|   | 2 |  No.2 Revision  | 
i've answered a smilar question before.
i trial code based on convexityDefects gives you some key points.maybe you will improve it.it or i will try to improve when i find time.
(also see smilar question i've answered with almost same code before.)
result images :
 
 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );
    if (src.empty())
        return -1;
    Mat bw;
    cvtColor( src, bw, COLOR_BGR2GRAY );
    bw = bw < 60;
    // Find contours
    vector<vector<Point> > contours;
    vector<int> contoursHull;
    vector<Vec4i> defects;
    findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    for ( size_t i = 0; i < contours.size(); i++)
    {
        if( contourArea(contours[i]) > 500 )
        {
            approxPolyDP(contours[i],contours[i],9,true);
            convexHull(contours[i], contoursHull,true);
            convexityDefects(contours[i], contoursHull,defects);
            for ( size_t j = 0; j <  defects.size(); j++)
            {
                Vec4i defpoint = defects[j];
                circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
            }
        }
    }
    imshow("result", src);
    waitKey();
    return 0;
}
|   | 3 |  No.3 Revision  | 
a trial code based on convexityDefects gives you some key points.maybe you will improve it or i will try to improve when i find time.
(also see smilar question i've answered with almost same code before.)
result images :
 
 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );
    if (src.empty())
        return -1;
    Mat bw;
    cvtColor( src, bw, COLOR_BGR2GRAY );
    bw = bw < 60;
    // Find contours
    vector<vector<Point> > contours;
    vector<int> contoursHull;
    vector<Vec4i> defects;
    findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    for ( size_t i = 0; i < contours.size(); i++)
    {
        if( contourArea(contours[i]) > 500 )
        {
            approxPolyDP(contours[i],contours[i],9,true);
            convexHull(contours[i], contoursHull,true);
            convexityDefects(contours[i], contoursHull,defects);
            for ( size_t j = 0; j <  defects.size(); j++)
            {
                Vec4i defpoint = defects[j];
                circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
            }
        }
    }
    imshow("result", src);
    waitKey();
    return 0;
}
EDIT 1: i tried to improve my solution by checking nonzero pixels count around the defect point.
result is perfect for the test images.
 
 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );
    if (src.empty())
        return -1;
    Mat bw;
    cvtColor( src, bw, COLOR_BGR2GRAY );
    bw = bw < 60;
    // Find contours
    vector<vector<Point> > contours;
    vector<int> contoursHull;
    vector<Vec4i> defects;
    findContours( bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    for ( size_t i = 0; i < contours.size(); i++)
    {
        if( contourArea(contours[i]) > 500 )
        {
            approxPolyDP(contours[i],contours[i],2,true);
            convexHull(contours[i], contoursHull,true);
            convexityDefects(contours[i], contoursHull,defects);
            for ( size_t j = 0; j <  defects.size(); j++)
            {
                Vec4i defpoint = defects[j];
                Point pt = contours[i][defpoint[2]]; // get defect point
                Rect r3x3(pt.x-2, pt.y-2, 5, 5 ); // create 5x5 Rect from defect point
                // maybe no need but to be sure that the rect is in the image
                r3x3 = r3x3 & Rect(0, 0, bw.cols, bw.rows );
                int non_zero_pixels = countNonZero( bw(r3x3) );
                cout << non_zero_pixels << endl;
                if( non_zero_pixels > 17 )
                    circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
            }
        }
    }
    imshow("result", src);
    waitKey();
    return 0;
}
|   | 4 |  No.4 Revision  | 
a trial code based on convexityDefects gives you some key points.maybe you will improve it or i will try to improve when i find time.
(also see smilar question i've answered with almost same code before.)
result images :
 
 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );
    if (src.empty())
        return -1;
    Mat bw;
    cvtColor( src, bw, COLOR_BGR2GRAY );
    bw = bw < 60;
    // Find contours
    vector<vector<Point> > contours;
    vector<int> contoursHull;
    vector<Vec4i> defects;
    findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE RETR_EXTERNAL, CHAIN_APPROX_NONE );
    for ( size_t i = 0; i < contours.size(); i++)
    {
        if( contourArea(contours[i]) > 500 )
        {
            approxPolyDP(contours[i],contours[i],9,true);
            convexHull(contours[i], contoursHull,true);
            convexityDefects(contours[i], contoursHull,defects);
            for ( size_t j = 0; j <  defects.size(); j++)
            {
                Vec4i defpoint = defects[j];
                circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
            }
        }
    }
    imshow("result", src);
    waitKey();
    return 0;
}
EDIT 1: i tried to improve my solution by checking nonzero pixels count around the defect point.
result is perfect for the test images.
 
 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );
    if (src.empty())
        return -1;
    Mat bw;
    cvtColor( src, bw, COLOR_BGR2GRAY );
    bw = bw < 60;
    // Find contours
    vector<vector<Point> > contours;
    vector<int> contoursHull;
    vector<Vec4i> defects;
    findContours( bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE RETR_EXTERNAL, CHAIN_APPROX_NONE );
    for ( size_t i = 0; i < contours.size(); i++)
    {
        if( contourArea(contours[i]) > 500 )
        {
            approxPolyDP(contours[i],contours[i],2,true);
            convexHull(contours[i], contoursHull,true);
            convexityDefects(contours[i], contoursHull,defects);
            for ( size_t j = 0; j <  defects.size(); j++)
            {
                Vec4i defpoint = defects[j];
                Point pt = contours[i][defpoint[2]]; // get defect point
                Rect r3x3(pt.x-2, pt.y-2, 5, 5 ); // create 5x5 Rect from defect point
                // maybe no need but to be sure that the rect is in the image
                r3x3 = r3x3 & Rect(0, 0, bw.cols, bw.rows );
                int non_zero_pixels = countNonZero( bw(r3x3) );
                cout << non_zero_pixels << endl;
                if( non_zero_pixels > 17 )
                    circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
            }
        }
    }
    imshow("result", src);
    waitKey();
    return 0;
}