You can view a sample image, apply some anti-aliasing and find the Otsu threshold, then use this threshold to find the Canny edge with different window sizes.
For a larger window ( 5 x 5 ) you get a noisy image that contains almost all the edges you need, plus noise. 
For a smaller window ( 3 x 3 ) you get a less noisy image, but some of the edges are missing. 
If this less noisy image is not good enough, you can try to morphologically restore it using a noisy image as a mask. Here I connected some diagonal edge segments in a noisy image using the morphological transform of misses, and then applied the reconstruction. 
Using
Mat k = (Mat_<int>(3, 3) << 0, 0, 1, 0, -1, 0, 1, 0, 0);
to bind broken ribs, you get a finer outline.

Note that in the c++ code below, I used naive reconstruction.
Mat im = imread("rsSUY.png", 0); pyrUp(im, im); GaussianBlur(im, im, Size(5, 5), 5); Mat bw1, bw2; double th = threshold(im, bw1, 0, 255, THRESH_BINARY | THRESH_OTSU); Canny(im, bw1, th, th/2, 5, true); Canny(im, bw2, th, th/2, 3, true); Mat k = (Mat_<int>(3, 3) << 0, 0, 1, 0, -1, 0, 0, 0, 0); Mat hitmiss; morphologyEx(bw1, hitmiss, MORPH_HITMISS, k); bw1 |= hitmiss; Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3)); double prevMu = 0; Mat recons = bw2.clone(); for (int i = 0; i < 200; i++) { dilate(recons, recons, kernel); recons &= bw1; Scalar mu = mean(recons); if (abs(mu.val[0] - prevMu) < 0.001) { break; } prevMu = mu.val[0]; } imshow("less noisy", bw2); imshow("reconstructed", recons); waitKey();