<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Olga Tatarinova</title>
    <description>The latest articles on DEV Community by Olga Tatarinova (@olga_tatarinova).</description>
    <link>https://dev.to/olga_tatarinova</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2846802%2Ffef998c1-67f8-41ea-8e44-04408f855fc8.png</url>
      <title>DEV Community: Olga Tatarinova</title>
      <link>https://dev.to/olga_tatarinova</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olga_tatarinova"/>
    <language>en</language>
    <item>
      <title>Open-source app for collecting field data for computer-vision projects</title>
      <dc:creator>Olga Tatarinova</dc:creator>
      <pubDate>Thu, 09 Jul 2026 02:01:36 +0000</pubDate>
      <link>https://dev.to/olga_tatarinova/open-source-app-for-collecting-field-data-for-computer-vision-projects-6j6</link>
      <guid>https://dev.to/olga_tatarinova/open-source-app-for-collecting-field-data-for-computer-vision-projects-6j6</guid>
      <description>&lt;p&gt;We build computer-vision systems for a living: shelves in stores, cattle on farms, parts on a conveyor. On almost every one, the thing that eats the lots of time is getting clean data out of the field.&lt;/p&gt;

&lt;p&gt;Usually it goes like this. You tell the client "just photograph your shelves," and you get a pile of images in WhatsApp and email, half of them blurry and dark, no idea which photo is which SKU or which animal. Then someone on your side copies them around by hand.&lt;/p&gt;

&lt;p&gt;Тraining the model is rather easy now. What decides whether you get a working system or a demo is the clear data, and it's grunt work and it's less fun than training models.&lt;/p&gt;

&lt;p&gt;What we learned collecting field data:&lt;/p&gt;

&lt;p&gt;Capture camera metadata at the source. Intrinsics (fx, fy, cx, cy, focal length) and EXIF should be saved with every photo. If you ever want to measure anything from the image, you need this at capture time and you cannot recover it later.&lt;/p&gt;

&lt;p&gt;Assume there is no signal on the mobile device. Save the capture on the device first, then upload with a resumable protocol, because a warehouse basement or a field will constantly drop your connection. Resume from the last unsent file.&lt;/p&gt;

&lt;p&gt;Guide the shot. Show the person a reference angle, and run a cheap on-device check for blur and exposure before the photo is saved. A two-second "retake this" prompt beats finding blurry captures later.&lt;/p&gt;

&lt;p&gt;Keep the collection scenario in config - what you collect and in what order should change with an edit to a config file.&lt;/p&gt;

&lt;p&gt;Bundle each capture as one unit. When someone submits, the form data and the photos (with their metadata) get packed into one record tied to the project. So an image never floats around on its own, and no one has to work out later which photo belongs to which cow or which shelf.&lt;/p&gt;

&lt;p&gt;We'd rebuilt some version of this for every project, so we finally made it a real thing and open-sourced it. A Flutter app for offline field capture, plus a Django admin to define projects and review what comes back. The scenario config lives in Git.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/epoch8/data-collector" rel="noopener noreferrer"&gt;https://github.com/epoch8/data-collector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's early: no background upload yet, but it already beats the messenger-and-spreadsheet loop, though.&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>opensource</category>
      <category>machinelearning</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Programmatic logo design for an ML agency</title>
      <dc:creator>Olga Tatarinova</dc:creator>
      <pubDate>Tue, 07 Jul 2026 12:09:03 +0000</pubDate>
      <link>https://dev.to/olga_tatarinova/programmatic-logo-design-for-an-ml-agency-bek</link>
      <guid>https://dev.to/olga_tatarinova/programmatic-logo-design-for-an-ml-agency-bek</guid>
      <description>&lt;p&gt;I've been running a small ML agency for ages, since before it was cool, and recently I got the urge to refresh the brand. Somewhere in that itch I decided the logo shouldn't be a saved file at all. It should compute itself in the browser, redrawn every frame from a formula. The company is called Epoch8, so the math had to earn the name.&lt;/p&gt;

&lt;p&gt;The name gives three hooks: the digit 8, the letter E, and epoch, which for an ML shop is a real word (one full pass over the training data). I wanted the mark to lean on all three.&lt;/p&gt;

&lt;p&gt;The 8 was the easy half. A Bernoulli lemniscate (r² = a²·cos 2θ) is the sideways infinity sign; stand it upright and it reads as a clean figure eight. Infinity as a cycle, an epoch as a cycle. It also survives down to favicon size, which a fussier curve won't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy62ini7arwqtr7c7nk46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy62ini7arwqtr7c7nk46.png" alt="Bernoulli lemniscate (r² = a²·cos 2θ)" width="376" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The E is where it got fun. No tidy formula draws a letter, so I went with a Fourier series: any closed outline can be redrawn by a stack of spinning circles, a big one for the gross shape and smaller ones adding detail. I sampled the E at 1024 points and ran a DFT. It hands the circles back in order of importance: the first few set the rough shape, and each extra one only adds finer detail. So if you draw just a handful you get a blobby E, and the more circles you add the more it sharpens into a clean letter. That sharpening is the convergence. Each circle is one harmonic, so I counted them off in eights and called every eight an epoch: the first 8 harmonics are epoch one (rough), 16 is epoch two (sharper), and the E tightens up epoch by epoch, the way accuracy climbs over training runs. That's the bit I got a kick out of.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn50jdhicbz7wgk4614q3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn50jdhicbz7wgk4614q3.gif" alt="E converges" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The nicest accident is Gibbs. A partial Fourier sum always overshoots at a sharp corner, and the overshoot never shrinks to zero, it just squeezes tighter against the corner (holds around 9% of the jump). That behaves just like a training loss that keeps dropping but never quite hits zero. So I left the ripple in. The convergence "stalls" the way real training does.&lt;/p&gt;

&lt;p&gt;One more piece: the name beside the mark needed a typeface, and since we are a shop full of programmers, a monospace font was the obvious call, the fixed-width kind you stare at all day in a code editor. I tried a handful and settled on JetBrains Mono, and the detail that sold me was its 8. Most fonts build an 8 from two stacked ovals that meet in a soft pinch. JetBrains Mono ExtraBold crosses it instead: the waist narrows to a sharp little beak, the same beak a lemniscate makes where it crosses itself in the middle. Lay the typed 8 over the math one and the two crossings land right on top of each other. So the wordmark's 8 rhymes with the logo's 8.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faq9rq6yht8dr77i1y45p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faq9rq6yht8dr77i1y45p.png" alt="JetBrains Mono ExtraBold" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fibmjr9ykwvtrqof0431q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fibmjr9ykwvtrqof0431q.png" alt="E8 team" width="512" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The convergence ladder earned its keep off the logo too. &lt;/p&gt;

&lt;p&gt;When we scope a build in a proposal, it usually comes in stages. The first is a bare proof that the thing works; the last is a system that runs on its own. &lt;/p&gt;

&lt;p&gt;A staged build is easy to describe badly: the client hears five phases and cannot tell well what changes between them. So we illustrate the stages with the mark itself, drawing each one as the E at a higher harmonic count. The early stage is the rough, low-harmonic E, blobby but already an E. The final stage is the crisp one. The client reads maturity as convergence: a letter you can recognize early, sharpening as it earns more of the work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdts2iteepckwvcwua0kf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdts2iteepckwvcwua0kf.jpeg" alt="Stages of E" width="799" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ladder is also an argument. Each stage is useful on its own, so the client can stop after any one and keep what they have. That mirrors the math: a partial Fourier sum is already a readable E long before it is exact.&lt;/p&gt;

&lt;p&gt;This tiny project is easily the most fun I have had with a logo :)&lt;/p&gt;

</description>
      <category>design</category>
      <category>website</category>
      <category>machinelearning</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
