Full Code of candycat1992/PencilDrawing for AI

master bca965d1c92a cached
6 files
8.2 KB
2.8k tokens
1 requests
Download .txt
Repository: candycat1992/PencilDrawing
Branch: master
Commit: bca965d1c92a
Files: 6
Total size: 8.2 KB

Directory structure:
gitextract__zisyvfe/

├── GenPencil.m
├── GenStroke.m
├── GenToneMap.m
├── PencilDrawing.m
├── README.md
└── demo.m

================================================
FILE CONTENTS
================================================

================================================
FILE: GenPencil.m
================================================
function T = GenPencil(im, P, J)
% ==============================================
%   Compute the pencil map 'T'
%  
%   Paras:
%   @im        : input image ranging value from 0 to 1.
%   @P         : the pencil texture.
%   @J         : the tone map.
%

    %% Parameters
    theta = 0.2;
    
    [H, W, ~] = size(im);

    %% Initialization
    P = imresize(P, [H, W]);
    P = reshape(P, H*W, 1);
    logP = log(P);
    logP = spdiags(logP, 0, H*W, H*W);
    
    J = imresize(J, [H, W]);
    J = reshape(J, H*W, 1);
    logJ = log(J);
    
    e = ones(H*W, 1);
    Dx = spdiags([-e, e], [0, H], H*W, H*W);
    Dy = spdiags([-e, e], [0, 1], H*W, H*W);
    
    %% Compute matrix A and b
    A = theta * (Dx * Dx' + Dy * Dy') + (logP)' * logP;
    b = (logP)' * logJ;
    
    %% Conjugate gradient
    beta = pcg(A, b, 1e-6, 60);
    
    %% Compute the result
    beta = reshape(beta, H, W);
    
    P = reshape(P, H, W);
    
    T = P .^ beta;
end

================================================
FILE: GenStroke.m
================================================
function S = GenStroke(im, ks, width, dirNum)
% ==============================================
%   Compute the stroke structure 'S'
%  
%   Paras:
%   @im        : input image ranging value from 0 to 1.
%   @ks        : kernel size.
%   @width     : width of the strocke
%   @dirNum    : number of directions.
%
    
    %% Initialization
    [H, W, ~] = size(im);
    
    %% Smoothing
    im = medfilt2(im, [3 3]);
    
    %% Image gradient
    imX = [abs(im(:,1:(end-1)) - im(:,2:end)),zeros(H,1)];
    imY = [abs(im(1:(end-1),:) - im(2:end,:));zeros(1,W)];  
    imEdge = imX + imY;

    %% Convolution kernel with horizontal direction 
    kerRef = zeros(ks*2+1);
    kerRef(ks+1,:) = 1;

    %% Classification 
    response = zeros(H,W,dirNum);
    for n = 1 : dirNum
        ker = imrotate(kerRef, (n-1)*180/dirNum, 'bilinear', 'crop');
        response(:,:,n) = conv2(imEdge, ker, 'same');
    end

    [~, index] = max(response,[], 3); 

    %% Create the stroke
    C = zeros(H, W, dirNum);
    for n = 1 : dirNum
        C(:,:,n) = imEdge .* (index == n);
    end

    kerRef = zeros(ks*2+1);
    kerRef(ks+1,:) = 1;
    for n = 1 : width
        if (ks+1-n) > 0
            kerRef(ks+1-n,:) = 1;
        end
        if (ks+1+n) < (ks*2+1)
            kerRef(ks+1+n,:) = 1;
        end
    end
    
    Spn = zeros(H, W, dirNum);
    for n = 1 : dirNum
        ker = imrotate(kerRef, (n-1)*180/dirNum, 'bilinear', 'crop');
        Spn(:,:,n) = conv2(C(:,:,n), ker, 'same');
    end

    Sp = sum(Spn, 3);
    Sp = (Sp - min(Sp(:))) / (max(Sp(:)) - min(Sp(:)));
    S = 1 - Sp;
end

================================================
FILE: GenToneMap.m
================================================
function J = GenToneMap(im)
% ==============================================
%   Compute the tone map 'T'
%  
%   Paras:
%   @im        : input image ranging value from 0 to 1.
%
    
    %% Parameters
    Ub = 225;
    Ua = 105;
    
    Mud = 90;
    
    DeltaB = 9;
    DeltaD = 11;
    
    % groups from dark to light
    % 1st group
    Omega1 = 42;
    Omega2 = 29;
    Omega3 = 29;
    % 2nd group
    Omega1 = 52;
    Omega2 = 37;
    Omega3 = 11;
    % 3rd group
    Omega1 = 76;
    Omega2 = 22;
    Omega3 = 2;
    
    %% Compute the target histgram
    histgramTarget = zeros(256, 1);
    total = 0;
    for ii = 0 : 255
        if ii < Ua || ii > Ub
            p = 0;
        else
            p = 1 / (Ub - Ua);
        end
        
        histgramTarget(ii+1, 1) = (...
            Omega1 * 1/DeltaB * exp(-(255-ii)/DeltaB) + ...
            Omega2 * p + ...
            Omega3 * 1/sqrt(2 * pi * DeltaD) * exp(-(ii-Mud)^2/(2*DeltaD^2))) * 0.01;
        
        total = total + histgramTarget(ii+1, 1);
    end
    histgramTarget(:, 1) = histgramTarget(:, 1)/total;

%     %% Smoothing
%     im = medfilt2(im, [5 5]);
    
    %% Histgram matching
    J = histeq(im, histgramTarget);
    
    %% Smoothing
    G = fspecial('average', 10);
    J = imfilter(J, G,'same');
end

================================================
FILE: PencilDrawing.m
================================================
function I = PencilDrawing(im, ks, width, dirNum, gammaS, gammaI)
% ==============================================
%   Generate the pencil drawing I based on the method described in
%   "Combining Sketch and Tone for Pencil Drawing Production" Cewu Lu, Li Xu, Jiaya Jia 
%   International Symposium on Non-Photorealistic Animation and Rendering (NPAR 2012), June, 2012
%  
%   Paras:
%   @im        : the input image.
%   @ks        : the length of convolution line.
%   @width     : the width of the stroke.
%   @dirNum    : the number of directions.
%   @gammaS    : the darkness of the stroke.
%   @gammaI    : the darkness of the resulted image.
%

    %% Read the image
    im = im2double(im);
    [H, W, sc] = size(im);

    %% Convert from rgb to yuv when nessesary
    if (sc == 3)
        yuvIm = rgb2ycbcr(im);
        lumIm = yuvIm(:,:,1);
    else
        lumIm = im;
    end

    %% Generate the stroke map
    S = GenStroke(lumIm, ks, width, dirNum) .^ gammaS; % darken the result by gamma
%     figure, imshow(S)

    %% Generate the tone map
    J = GenToneMap(lumIm) .^ gammaI; % darken the result by gamma
%     figure, imshow(J)

    %% Read the pencil texture
    P = im2double(imread('pencils/pencil0.jpg'));
    P = rgb2gray(P);

    %% Generate the pencil map
    T = GenPencil(lumIm, P, J);
%     figure, imshow(T)

    %% Compute the result
    lumIm = S .* T;

    if (sc == 3)
        yuvIm(:,:,1) = lumIm;
    %     resultIm = lumIm;
        I = ycbcr2rgb(yuvIm);
    else
        I = lumIm;
    end
end



================================================
FILE: README.md
================================================

# Introduction

Implement the algorithm presented in [1]. You can use the code like below to get a pencil drawing production:

```C++
I = PencilDrawing(im, ks, width, dirNum, gammaS, gammaI);
```

See demo.m for example.

# Parameters

I added some more parameters for better control of the final image.

* **width**

	Control the width of the strokes. See Figure 1 for example.

	![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/results/width0.png) ![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/results/width1.png)

	**Figure 1**: Width of the strokes. left: width = 0; right: width = 2.

* **gammaS**

	Control the darkness of the strokes. See Figure 2 for example.

	![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/results/stroke_dark0.png) ![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/results/stroke_dark1.png)

	**Figure 2**: Gamma of the strokes. left: gammaS = 1.0; right: gammaS = 2.0.

* **gammaI**

	Control the darkness of the final image. See Figure 3 for example.

	![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/results/image_dark0.png) ![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/results/image_dark1.png)

	**Figure 3**: Gamma of the final image. left: gammaI = 1.0; right: gammaI = 0.4.

## Tone Transfer Weights

The paper presented three groups of weights for tone map generation.

1. ![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/project_images/Tex2Img_1448535264.jpg)

2. ![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/project_images/Tex2Img_1448535306.jpg)

3. ![alt text](https://github.com/candycat1992/PencilDrawing/blob/master/project_images/Tex2Img_1448535007.jpg)

These weights will determine the histogram of the tone map. I use the third group by default, which makes the final image lighter. You can change to other groups in GenToneMap.m.

# Folder Organization

* **inputs**

	Include some test images from <a href="http://www.cse.cuhk.edu.hk/leojia/projects/pencilsketch/pencil_drawing.htm" target="_blank">the website </a> of the publishers and other images.

* **pencils**
	
	Include 5 pencil textures for demonstration. I use “pencils/pencil0.jpg” by default. You can change it in PencilDrawing.m.

* **results**

	Include the results generated by my code. Each image may use different parameters.

* **resultsFromPaper**

	Include the results of the paper for comparison. I grabbed them in <a href="http://www.cse.cuhk.edu.hk/leojia/projects/pencilsketch/pencil_drawing.htm" target="_blank">their website</a>.

# Reference

[1] Lu C, Xu L, Jia J. Combining sketch and tone for pencil drawing production[C]//Proceedings of the Symposium on Non-Photorealistic Animation and Rendering. Eurographics Association, 2012: 65-73.


================================================
FILE: demo.m
================================================

im = imread('inputs/15--298.jpg');

I = PencilDrawing(im, 8, 1, 8, 1.0, 1.0);

figure, imshow(I)
Download .txt
gitextract__zisyvfe/

├── GenPencil.m
├── GenStroke.m
├── GenToneMap.m
├── PencilDrawing.m
├── README.md
└── demo.m
Condensed preview — 6 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (9K chars).
[
  {
    "path": "GenPencil.m",
    "chars": 956,
    "preview": "function T = GenPencil(im, P, J)\n% ==============================================\n%   Compute the pencil map 'T'\n%  \n%  "
  },
  {
    "path": "GenStroke.m",
    "chars": 1653,
    "preview": "function S = GenStroke(im, ks, width, dirNum)\r\n% ==============================================\r\n%   Compute the stroke "
  },
  {
    "path": "GenToneMap.m",
    "chars": 1292,
    "preview": "function J = GenToneMap(im)\n% ==============================================\n%   Compute the tone map 'T'\n%  \n%   Paras:"
  },
  {
    "path": "PencilDrawing.m",
    "chars": 1588,
    "preview": "function I = PencilDrawing(im, ks, width, dirNum, gammaS, gammaI)\r\n% ==============================================\r\n%  "
  },
  {
    "path": "README.md",
    "chars": 2849,
    "preview": "\n# Introduction\n\nImplement the algorithm presented in [1]. You can use the code like below to get a pencil drawing produ"
  },
  {
    "path": "demo.m",
    "chars": 97,
    "preview": "\nim = imread('inputs/15--298.jpg');\n\nI = PencilDrawing(im, 8, 1, 8, 1.0, 1.0);\n\nfigure, imshow(I)"
  }
]

About this extraction

This page contains the full source code of the candycat1992/PencilDrawing GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 6 files (8.2 KB), approximately 2.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!