Continuous line drawing from halftoned image

Hello, I would like to make one continuous line through all points in a binary image that I have halftoned. I also made a structuring element with strel('line') and the output looks good except I want a continuous line, so if it's easier to make a continuous line out of that image than just the purely halftoned image, that is fine too.
Things I have tried:
  • using two line structuring elements and the 'imclose' filter twice, one line at 45 degrees and the next at 135 (so they are perpendicular structuring elements and I'm proccessing the image twice to try to create overlap)
  • using the 'imdilate' filter
  • researching nearest neighbor searches, but haven't found anything that I can make sense out of at my level of knowledge
  • making a 'sine wave' function that varies its amplitude with the 'brightness' of the image - so block processing an area and going through and transforming the sine wave function to look brighter or darker depending on region of image being on average brighter or darker in that block. I would love to do this but I'm stuck on how to even plot the output. I have a binary image so I think I understand that I would evaluate the 'brightness' by taking average of a block and then I have a 0 - 255 value representing the level of 'brightness'. At that point I understand I'd need some math to phase shift the sine wave if I adjusted the frequency, but going a simpler route I'd like to just use amplitude modulation and line up the period of the sine wave with the amount of actual pixels (so period*n = width of block in pixels)in the block I'm processing so that I don't have to do this? Then I would just make a border to connect every wave.
I know the sine wave thing is out there but if my level of understanding is just connecting the lines then that's perfectly fine, haha.
I'll include my code so far below as well as three output images, the halftoned image, the 'line drawing' images @45 degrees and 0 degrees.
Note: You'll see I have made my code so that it automatically crops the image to square so that the matrix manipulations are easier.
im = imread('FaceRGB.jpg');
im=im2double(im);
sizes = size(im);
r = sizes(1);
c = sizes(2);
if r<c
N = r;
else
N = c;
end
targetsize = [N, N];
re = centerCropWindow2d(sizes,targetsize);
squareimage = imcrop(im, re);
im = rgb2gray(squareimage);
im=im2double(im);
im = imresize(im, 0.125);
im = imresize(im, 8);
[s1, s2]=size(im);
MAT=[24 10 12 26 35 47 49 37;
08 00 02 14 45 59 61 51;
22 06 04 16 43 57 63 53;
30 20 18 28 33 41 55 39;
34 46 48 36 25 11 13 27;
44 58 60 50 09 01 03 15;
42 56 62 52 23 07 05 17;
32 40 54 38 31 21 19 29;]/64;
r = (s1/8);
c = (s2/8);
mask=repmat(MAT,[r c]);
Halftone =im>mask;
image = imshow(Halftone);
imwrite(Halftone, 'face_halftone.tiff');
se = strel('line', 10, 45);
image2 = imclose(Halftone, se);
figure, imshow(image2)
imwrite(image2, 'face_lines.tiff');

 Accepted Answer

Turn the image into a gray scale image by using blockproc(). See attached demo.
Then you can use multiple thresholds to get each region. Then use each region as a mask on an image of stripes to get stripes only in that region.

2 Comments

Seems like you're having a lot of trouble since there's been no response from you. So here is a start. See if you can finish it.
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
fileName = 'Halftoned_Image.jpg';
grayImage = imread(fileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Extract the blue channel (so the magenta lines will be white).
grayImage = grayImage(:, :, 3);
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 1, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
caption = sprintf('Original image is %d rows by %d columns', rows, columns);
title(caption, 'FontSize', fontSize);
hold on
drawnow;
% Maximize window.
g = gcf;
g.WindowState = 'maximized'
drawnow;
%===============================================================================================================================
% MEAN of 8 pixel by 8 pixel block
% Block process the image to replace every pixel in the
% 8 pixel by 8 pixel block by the mean of the pixels in the block.
% Image will be smaller since we are not using ones() and so for each block
% there will be just one output pixel, not a block of 8 by 8 output pixels.
% Define a filter function that will give 1 pixel as output for every 2-D block of input.
meanFilterFunction = @(theBlockStructure) mean(theBlockStructure.data(:));
blockSize = [8, 8];
blockyImage8811 = blockproc(grayImage, blockSize, meanFilterFunction);
[rows, columns] = size(blockyImage8811);
% Display the block filtered image.
subplot(2, 1, 2);
imshow(blockyImage8811, []);
axis('on', 'image');
impixelinfo;
caption = sprintf('Block Mean Output Image\n32 blocks. Input block size = %d, output block size = 1\nOutput image is %d rows by %d columns', blockSize(1), rows, columns);
title(caption, 'FontSize', fontSize);
drawnow; % Force screen to refresh immediately.
Thank you that definitely helps a lot! I had just looked at your first comment didn't mean to not reply! This is very useful.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!