Load the input image as grayscale.
Step 1
Dilate the image, in order to get rid of the text. This step somewhat helps to preserve the bar code.
Step 2
Median blur the result with a decent sized kernel to further suppress any text.
This should get us a fairly good background image that contains all the shadows and/or discoloration.
Step 3
Calculate the difference between the original and the background we just obtained. The bits that are identical will be black (close to 0 difference), the text will be white (large difference).
Since we want black on white, we invert the result.
Step 4
Normalize the image, so that we use the full dynamic range.
Step 5
At this point we still have the paper somewhat gray. We can truncate that away, and re-normalize the image.