元の画像の輝度勾配に応じて,適当に結果画像の輝度を決定すればよいのではないでしょうか.
Sobelフィルタのようなエッジ検出フィルタの結果値から,輝度勾配の強度を見積もることができるでしょう.
例えば,良く見る 3x3 の Sobelフィルタ:
と
から求まる2つの結果値{SX,SY}から,
輝度勾配の強度 = sqrt( SX*SX + SY*SY )
とか何とかして見積ればよいでしょう.
あとはてきとーにその値の大小に応じた結果画像を描画するだけですね.
てきとーな例を追加(コードはC++ですが)
結果画像:上から{入力,Cannyの結果,Sobelから求めた強度に基づくてきとーな明暗描画結果}
C++
1int main()
2{
3 cv::Mat Src = cv::imread( "Kuro.png", cv::IMREAD_GRAYSCALE );
4 if( Src.empty() )return 0;
5 //Sobel
6 cv::Mat SX( Src.size(), CV_16S );
7 cv::Mat SY( Src.size(), CV_16S );
8 cv::Sobel( Src, SX, CV_16S, 1, 0 );
9 cv::Sobel( Src, SY, CV_16S, 0, 1 );
10 //Canny
11 cv::Mat Mask;
12 cv::Canny( Src, Mask, 100, 50 );
13 //ShowImgは単なる表示用
14 cv::Mat ShowImg;
15 cv::vconcat( Src, Mask, ShowImg );
16
17 //Maskの内容をSobelの結果を用いて明暗がついた感じに更新
18 for( int y=0; y<Src.rows; ++y )
19 {
20 unsigned char *pMask = Mask.ptr<unsigned char>(y);
21 const short *pSX = SX.ptr<short>(y);
22 const short *pSY = SY.ptr<short>(y);
23 for( int x=0; x<Src.cols; ++x, ++pMask, ++pSX, ++pSY )
24 {
25 if( !*pMask )continue;
26 auto Mag = sqrt( (*pSX * *pSX) + (*pSY * *pSY) );
27 *pMask = (unsigned char)( std::min(Mag, 255.0) );
28 }
29 }
30
31 //結果表示
32 cv::vconcat( ShowImg, Mask, ShowImg );
33 cv::imshow( "Result", ShowImg );
34 if( cv::waitKey() == 's' ){ cv::imwrite( "Result.png", ShowImg ); }
35 return 0;
36}