From link:

Black-to-White transition is taken as Positive slope (it has a positive value) while White-to-Black transition is taken as a Negative slope (It has negative value). So when you convert data to np.uint8, all negative slopes are made zero. In simple words, you miss that edge.

So all i want is to write a function so i can keep negative gradient values. I know how to use Sobel.

Here is the sobel link where I got to know light-to-dark, dark-to-light are gradient directions, which are also referred as $+\text ve$ and $-\text ve$ directions.

IMPROVED Question: Please Suggest me a logic of the function to retain only $-\text ve$ values and clip $+\text ve$ values to zero?

My code:

Sobel(grayImg, grad, CV_16S, 0, 1, -1, BORDER_DEFAULT);
         gradCpy = grad.clone();
         for(uint64_t i=0; i <(gradCpy.rows); i++)
        for(uint64_t j=0; j<(gradCpy.cols); j++)
            if ((gradCpy.data[((gradCpy.step/gradCpy.elemSize()))*i+j]) > 0) {(gradCpy.data[(gradCpy.step/gradCpy.elemSize())*i+j]) = (int32_t)-0.0;} ///nega gradient img
            //if ((gradCpy.data[((gradCpy.step/gradCpy.elemSize()))*i+j]) < 0.0) {gradCpy.data[((gradCpy.step/gradCpy.elemSize()))*i+j] = (int16_t)+0.0;}   ///pos gradient img
    convertScaleAbs(gradCpy, opImg2);
    imshow("negative grad", opImg2);

But i am not getting expected results. As per Sobel link, I want to get edge at black-to-white that is $+\text ve$ gradient and another one at white-to-black that is $-\text ve$ gradient

  • $\begingroup$ Where is $-\text ve$ or $+\text ve$ in your link ? $\endgroup$
    – Gilles
    Oct 20 '15 at 20:09
  • $\begingroup$ positive gradient and negative gradient are one and the same as light-to-dark and dark-to-light gradients. $\endgroup$
    – Mandar
    Oct 21 '15 at 11:07

The UINT8 type is limited to integer numbers on the range [0, 1, 2, ..., 255].
Hence negative values are clipped into 0.

A solution could be wither use other types (Floating Points) or scale and shift.

For instance, given a Floating Point image with values imageMax and imageMean you can scale it into the [0, 1, 2, ..., 255] by doing:

  1. Create only positive numbers: image - imageMin.
  2. Scale it into the range: round(255 * (image - imageMin) / (imageMax - imageMin)).

Now the conversion won't loose data.

Others have different approach, set 128 to be zero.
Namely, add 128 to the image, clip it into [0, 255] and then convert to UINT8.


  • $\begingroup$ I am aware of uint8 data type. I can use float to preserve values less than zero. What i want is only a logic, which stores negative values and clips positive values to 0. $\endgroup$
    – Mandar
    Oct 21 '15 at 11:11
  • $\begingroup$ What do you mean? Logic of what? $\endgroup$
    – Royi
    Oct 21 '15 at 16:57
  • $\begingroup$ Please see my question once more. $\endgroup$
    – Mandar
    Oct 28 '15 at 11:42
  • $\begingroup$ I still don't understand... $\endgroup$
    – Royi
    Oct 28 '15 at 13:39
  • $\begingroup$ @Mandar if you only want to store the negative values, then negate all the gradients before you convert the results to a uint8. Any values that are negative after negation should be set to zero. $\endgroup$
    – Simon B
    Oct 29 '15 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.